diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index 974273dc6854dd..bae76f0ce3d759 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -c3e20f18fe37993ddcbf11dccb55663b4c0d02fd \ No newline at end of file +0cf9fc10ba9d47099f3507080dd736054d877a20 \ No newline at end of file diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index 4d07117f346fb9..5d488ee7b2f9d1 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -1237,10 +1237,10 @@ var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; -var FundamentalComponent = 20; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; +var CacheComponent = 24; /** * Instance of element that should respond to touch/move types of interactions, @@ -2493,14 +2493,27 @@ function getFiberCurrentPropsFromNode$1(inst) { // Module provided by RN: var ReactFabricGlobalResponderHandler = { onChange: function(from, to, blockNativeResponder) { - if (to !== null) { - var tag = to.stateNode.canonical._nativeTag; - ReactNativePrivateInterface.UIManager.setJSResponder( - tag, - blockNativeResponder - ); + var fromOrTo = from || to; + var isFabric = !!fromOrTo.stateNode.canonical._internalInstanceHandle; + + if (isFabric) { + if (from) { + nativeFabricUIManager.setIsJSResponder(from.stateNode.node, false); + } + + if (to) { + nativeFabricUIManager.setIsJSResponder(to.stateNode.node, true); + } } else { - ReactNativePrivateInterface.UIManager.clearJSResponder(); + if (to !== null) { + var tag = to.stateNode.canonical._nativeTag; + ReactNativePrivateInterface.UIManager.setJSResponder( + tag, + blockNativeResponder + ); + } else { + ReactNativePrivateInterface.UIManager.clearJSResponder(); + } } } }; @@ -2547,12 +2560,12 @@ var REACT_SUSPENSE_TYPE = 0xead1; var REACT_SUSPENSE_LIST_TYPE = 0xead8; var REACT_MEMO_TYPE = 0xead3; var REACT_LAZY_TYPE = 0xead4; -var REACT_FUNDAMENTAL_TYPE = 0xead5; var REACT_SCOPE_TYPE = 0xead7; var REACT_OPAQUE_ID_TYPE = 0xeae0; var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; var REACT_OFFSCREEN_TYPE = 0xeae2; var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; +var REACT_CACHE_TYPE = 0xeae4; if (typeof Symbol === "function" && Symbol.for) { var symbolFor = Symbol.for; @@ -2568,12 +2581,12 @@ if (typeof Symbol === "function" && Symbol.for) { REACT_SUSPENSE_LIST_TYPE = symbolFor("react.suspense_list"); REACT_MEMO_TYPE = symbolFor("react.memo"); REACT_LAZY_TYPE = symbolFor("react.lazy"); - REACT_FUNDAMENTAL_TYPE = symbolFor("react.fundamental"); REACT_SCOPE_TYPE = symbolFor("react.scope"); REACT_OPAQUE_ID_TYPE = symbolFor("react.opaque.id"); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2647,6 +2660,9 @@ function getComponentName(type) { case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + + case REACT_CACHE_TYPE: + return "Cache"; } if (typeof type === "object") { @@ -2684,8 +2700,10 @@ function getComponentName(type) { // The rest of the flags are static for better dead code elimination. var enableProfilerTimer = true; +var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; +var deferRenderPhaseUpdateToNextBatch = true; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -2703,53 +2721,84 @@ var Update = 4; var PlacementAndUpdate = /* */ - 6; -var Deletion = - /* */ - 8; + Placement | Update; +var ChildDeletion = + /* */ + 16; var ContentReset = /* */ - 16; + 32; var Callback = /* */ - 32; + 64; var DidCapture = /* */ - 64; + 128; var Ref = /* */ - 128; + 256; var Snapshot = /* */ - 256; + 512; var Passive = /* */ - 512; + 1024; var Hydrating = /* */ - 1024; + 2048; var HydratingAndUpdate = /* */ - 1028; + Hydrating | Update; +var Visibility = + /* */ + 4096; var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ - 4095; // These are not really side effects, but we still reuse this field. + 8191; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ - 4096; + 8192; var ShouldCapture = /* */ - 8192; // TODO (effects) Remove this bit once the new reconciler is synced to the old. + 16384; // TODO (effects) Remove this bit once the new reconciler is synced to the old. var PassiveUnmountPendingDev = /* */ - 16384; + 32768; var ForceUpdateForLegacySuspense = /* */ - 32768; // Static tags describe aspects of a fiber that are not specific to a render, + 65536; // Static tags describe aspects of a fiber that are not specific to a render, +// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). +// This enables us to defer more work in the unmount case, +// since we can defer traversing the tree during layout to look for Passive effects, +// and instead rely on the static flag as a signal that there may be cleanup work. + +var PassiveStatic = + /* */ + 131072; // These flags allow us to traverse to fibers that have effects on mount +// don't contain effects, by checking subtreeFlags. + +var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity + // flag logic (see #20043) + Update | Snapshot | 0; +var MutationMask = + Placement | + Update | + ChildDeletion | + ContentReset | + Ref | + Hydrating | + Visibility; +var LayoutMask = Update | Callback | Ref; // TODO: Split into PassiveMountMask and PassiveUnmountMask + +var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. +// This allows certain concepts to persist without recalculting them, +// e.g. whether a subtree contains passive effects or portals. + +var StaticMask = PassiveStatic; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -2989,38 +3038,28 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null + ? findCurrentHostFiberImpl(currentParent) + : null; +} - if (!currentParent) { - return null; - } // Next we'll drill down this component to find the first HostComponent/Text. - - var node = currentParent; - - while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - return node; - } else if (node.child) { - node.child.return = node; - node = node.child; - continue; - } +function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } - if (node === currentParent) { - return null; - } + var child = node.child; - while (!node.sibling) { - if (!node.return || node.return === currentParent) { - return null; - } + while (child !== null) { + var match = findCurrentHostFiberImpl(child); - node = node.return; + if (match !== null) { + return match; } - node.sibling.return = node.return; - node = node.sibling; - } // Flow needs the return null here, but ESLint complains about it. - // eslint-disable-next-line no-unreachable + child = child.sibling; + } return null; } @@ -3689,2031 +3728,2079 @@ function dispatchEvent(target, topLevelType, nativeEvent) { // where it would do it. } -// can re-export everything from this module. +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -function shim() { - { +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" ); } -} // Mutation (when unsupported) +} -var supportsMutation = false; -var commitMount = shim; -var clearContainer = shim; +// Except for NoPriority, these correspond to Scheduler priorities. We use +// ascending numbers so we can compare them like numbers. They start at 90 to +// avoid clashing with Scheduler's priorities. +var ImmediatePriority = 99; +var UserBlockingPriority = 98; +var NormalPriority = 97; +var LowPriority = 96; +var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. -// can re-export everything from this module. +var NoPriority = 90; +var shouldYield = Scheduler_shouldYield; +var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. + Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; +var syncQueue = null; +var immediateQueueCallbackNode = null; +var isFlushingSyncQueue = false; +var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. +// This will be the case for modern browsers that support `performance.now`. In +// older browsers, Scheduler falls back to `Date.now`, which returns a Unix +// timestamp. In that case, subtract the module initialization time to simulate +// the behavior of performance.now and keep our times small enough to fit +// within 32 bits. +// TODO: Consider lifting this into Scheduler. -function shim$1() { - { - throw Error( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." - ); - } -} // Hydration (when unsupported) -var isSuspenseInstancePending = shim$1; -var isSuspenseInstanceFallback = shim$1; -var hydrateTextInstance = shim$1; +var now = + initialTimeMs < 10000 + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return ImmediatePriority; -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, - cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage.createChildSet, - appendChildNode = _nativeFabricUIManage.appendChild, - appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, - completeRoot = _nativeFabricUIManage.completeRoot, - registerEventHandler = _nativeFabricUIManage.registerEventHandler, - fabricMeasure = _nativeFabricUIManage.measure, - fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, - fabricMeasureLayout = _nativeFabricUIManage.measureLayout, - sendAccessibilityEvent = _nativeFabricUIManage.sendAccessibilityEvent; -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. -// % 10 === 1 means it is a rootTag. -// % 2 === 0 means it is a Fabric tag. -// This means that they never overlap. + case Scheduler_UserBlockingPriority: + return UserBlockingPriority; -var nextReactTag = 2; + case Scheduler_NormalPriority: + return NormalPriority; -// TODO: Remove this conditional once all changes have propagated. -if (registerEventHandler) { - /** - * Register the event emitter with the native bridge - */ - registerEventHandler(dispatchEvent); -} -/** - * This is used for refs on host components. - */ + case Scheduler_LowPriority: + return LowPriority; -var ReactFabricHostComponent = /*#__PURE__*/ (function() { - function ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ) { - this._nativeTag = tag; - this.viewConfig = viewConfig; - this.currentProps = props; - this._internalInstanceHandle = internalInstanceHandle; - } + case Scheduler_IdlePriority: + return IdlePriority; - var _proto = ReactFabricHostComponent.prototype; + default: { + throw Error("Unknown priority level."); + } + } +} - _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case ImmediatePriority: + return Scheduler_ImmediatePriority; - _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; + case UserBlockingPriority: + return Scheduler_UserBlockingPriority; - _proto.measure = function measure(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; + case NormalPriority: + return Scheduler_NormalPriority; - _proto.measureInWindow = function measureInWindow(callback) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; + case LowPriority: + return Scheduler_LowPriority; - _proto.measureLayout = function measureLayout( - relativeToNativeNode, - onSuccess, - onFail - ) /* currently unused */ - { - if ( - typeof relativeToNativeNode === "number" || - !(relativeToNativeNode instanceof ReactFabricHostComponent) - ) { - { - error( - "Warning: ref.measureLayout must be called with a ref to a native component." - ); - } + case IdlePriority: + return Scheduler_IdlePriority; - return; + default: { + throw Error("Unknown priority level."); } + } +} - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; +function runWithPriority(reactPriorityLevel, fn) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(priorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(priorityLevel, callback, options); +} +function scheduleSyncCallback(callback) { + // Push this callback into an internal queue. We'll flush these either in + // the next tick, or earlier if something calls `flushSyncCallbackQueue`. + if (syncQueue === null) { + syncQueue = [callback]; // TODO: Figure out how to remove this It's only here as a last resort if we + // forget to explicitly flush. - _proto.setNativeProps = function setNativeProps(nativeProps) { { - error("Warning: setNativeProps is not currently supported in Fabric"); + // Flush the queue in the next tick. + immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ); } - - return; - }; - - return ReactFabricHostComponent; -})(); // eslint-disable-next-line no-unused-expressions -function appendInitialChild(parentInstance, child) { - appendChildNode(parentInstance.node, child.node); -} -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = nextReactTag; - nextReactTag += 2; - var viewConfig = getViewConfigForType(type); - - { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); - } - } - } - - var updatePayload = create(props, viewConfig.validAttributes); - var node = createNode( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload, // props - internalInstanceHandle // internalInstanceHandle - ); - var component = new ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ); - return { - node: node, - canonical: component - }; -} -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - if (!hostContext.isInAParentText) { - throw Error("Text strings must be rendered within a component."); - } - - var tag = nextReactTag; - nextReactTag += 2; - var node = createNode( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { - text: text - }, // props - internalInstanceHandle // instance handle - ); - return { - node: node - }; -} -function getRootHostContext(rootContainerInstance) { - return { - isInAParentText: false - }; -} -function getChildHostContext(parentHostContext, type, rootContainerInstance) { - var prevIsInAParentText = parentHostContext.isInAParentText; - var isInAParentText = - type === "AndroidTextInput" || // Android - type === "RCTMultilineTextInputView" || // iOS - type === "RCTSinglelineTextInputView" || // iOS - type === "RCTText" || - type === "RCTVirtualText"; - - if (prevIsInAParentText !== isInAParentText) { - return { - isInAParentText: isInAParentText - }; } else { - return parentHostContext; + // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); } } -function getPublicInstance(instance) { - return instance.canonical; -} -function prepareForCommit(containerInfo) { - // Noop - return null; +function cancelCallback(callbackNode) { + Scheduler_cancelCallback(callbackNode); } -function prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - hostContext -) { - var viewConfig = instance.canonical.viewConfig; - var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // TODO: If the event handlers have changed, we need to update the current props - // in the commit phase but there is no host config hook to do it yet. - // So instead we hack it by updating it in the render phase. +function flushSyncCallbackQueue() { + if (immediateQueueCallbackNode !== null) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } - instance.canonical.currentProps = newProps; - return updatePayload; -} -function resetAfterCommit(containerInfo) { - // Noop + flushSyncCallbackQueueImpl(); } -function shouldSetTextContent(type, props) { - // TODO (bvaughn) Revisit this decision. - // Always returning false simplifies the createInstance() implementation, - // But creates an additional child Fiber for raw text children. - // No additional native views are created though. - // It's not clear to me which is better so I'm deferring for now. - // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 - return false; -} // The Fabric renderer is secondary to the existing React Native renderer. -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; // ------------------- -function cloneInstance( - instance, - updatePayload, - type, - oldProps, - newProps, - internalInstanceHandle, - keepChildren, - recyclableInstance -) { - var node = instance.node; - var clone; - if (keepChildren) { - if (updatePayload !== null) { - clone = cloneNodeWithNewProps(node, updatePayload); - } else { - clone = cloneNode(node); - } - } else { - if (updatePayload !== null) { - clone = cloneNodeWithNewChildrenAndProps(node, updatePayload); - } else { - clone = cloneNodeWithNewChildren(node); - } - } +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { + // Prevent re-entrancy. + isFlushingSyncQueue = true; + var i = 0; - return { - node: clone, - canonical: instance.canonical - }; -} -function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { - var viewConfig = instance.canonical.viewConfig; - var node = instance.node; - var updatePayload = create( { - style: { - display: "none" + try { + var _isSync2 = true; + var _queue = syncQueue; + runWithPriority(ImmediatePriority, function() { + for (; i < _queue.length; i++) { + var callback = _queue[i]; + + do { + callback = callback(_isSync2); + } while (callback !== null); + } + }); + syncQueue = null; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); + } // Resume flushing in the next tick + + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ); + throw error; + } finally { + isFlushingSyncQueue = false; } - }, - viewConfig.validAttributes - ); - return { - node: cloneNodeWithNewProps(node, updatePayload), - canonical: instance.canonical - }; -} -function cloneHiddenTextInstance(instance, text, internalInstanceHandle) { - throw new Error("Not yet implemented."); -} -function createContainerChildSet(container) { - return createChildNodeSet(container); -} -function appendChildToContainerChildSet(childSet, child) { - appendChildNodeToSet(childSet, child.node); -} -function finalizeContainerChildren(container, newChildren) { - completeRoot(container, newChildren); -} -function makeClientIdInDEV(warnOnAccessInDEV) { - throw new Error("Not yet implemented"); -} -function preparePortalMount(portalInstance) { - // noop + } + } } -// Helpers to patch console.logs to avoid logging during side-effect free -// replaying on render function. This currently only patches the object -// lazily which won't cover if the log function was extracted eagerly. -// We could also eagerly patch the method. -var disabledDepth = 0; -var prevLog; -var prevInfo; -var prevWarn; -var prevError; -var prevGroup; -var prevGroupCollapsed; -var prevGroupEnd; - -function disabledLog() {} +var SyncLanePriority = 15; +var SyncBatchedLanePriority = 14; +var InputDiscreteHydrationLanePriority = 13; +var InputDiscreteLanePriority = 12; +var InputContinuousHydrationLanePriority = 11; +var InputContinuousLanePriority = 10; +var DefaultHydrationLanePriority = 9; +var DefaultLanePriority = 8; +var TransitionHydrationPriority = 7; +var TransitionPriority = 6; +var RetryLanePriority = 5; +var SelectiveHydrationLanePriority = 4; +var IdleHydrationLanePriority = 3; +var IdleLanePriority = 2; +var OffscreenLanePriority = 1; +var NoLanePriority = 0; // Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler. +// If those values are changed that package should be rebuilt and redeployed. -disabledLog.__reactDisabledLog = true; -function disableLogs() { - { - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - prevLog = console.log; - prevInfo = console.info; - prevWarn = console.warn; - prevError = console.error; - prevGroup = console.group; - prevGroupCollapsed = console.groupCollapsed; - prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 +var TotalLanes = 31; +var NoLanes = + /* */ + 0; +var NoLane = + /* */ + 0; +var SyncLane = + /* */ + 1; +var SyncBatchedLane = + /* */ + 2; +var InputDiscreteHydrationLane = + /* */ + 4; +var InputDiscreteLane = + /* */ + 8; +var InputContinuousHydrationLane = + /* */ + 16; +var InputContinuousLane = + /* */ + 32; +var DefaultHydrationLane = + /* */ + 64; +var DefaultLane = + /* */ + 128; +var TransitionHydrationLane = + /* */ + 256; +var TransitionLanes = + /* */ + 8388096; +var TransitionLane1 = + /* */ + 512; +var TransitionLane2 = + /* */ + 1024; +var TransitionLane3 = + /* */ + 2048; +var TransitionLane4 = + /* */ + 4096; +var TransitionLane5 = + /* */ + 8192; +var TransitionLane6 = + /* */ + 16384; +var TransitionLane7 = + /* */ + 32768; +var TransitionLane8 = + /* */ + 65536; +var TransitionLane9 = + /* */ + 131072; +var TransitionLane10 = + /* */ + 262144; +var TransitionLane11 = + /* */ + 524288; +var TransitionLane12 = + /* */ + 1048576; +var TransitionLane13 = + /* */ + 2097152; +var TransitionLane14 = + /* */ + 4194304; +var RetryLanes = + /* */ + 125829120; +var RetryLane1 = + /* */ + 8388608; +var RetryLane2 = + /* */ + 16777216; +var RetryLane3 = + /* */ + 33554432; +var RetryLane4 = + /* */ + 67108864; +var SomeRetryLane = RetryLane1; +var SelectiveHydrationLane = + /* */ + 134217728; +var NonIdleLanes = + /* */ + 268435455; +var IdleHydrationLane = + /* */ + 268435456; +var IdleLane = + /* */ + 536870912; +var OffscreenLane = + /* */ + 1073741824; // This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler) +var NoTimestamp = -1; +var nextTransitionLane = TransitionLane1; +var nextRetryLane = RetryLane1; +// Used by getHighestPriorityLanes and getNextLanes: - var props = { - configurable: true, - enumerable: true, - value: disabledLog, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. +var return_highestLanePriority = DefaultLanePriority; - Object.defineProperties(console, { - info: props, - log: props, - warn: props, - error: props, - group: props, - groupCollapsed: props, - groupEnd: props - }); - /* eslint-enable react-internal/no-production-logging */ - } +function getHighestPriorityLanes(lanes) { + switch (getHighestPriorityLane(lanes)) { + case SyncLane: + return_highestLanePriority = SyncLanePriority; + return SyncLane; - disabledDepth++; - } -} -function reenableLogs() { - { - disabledDepth--; + case SyncBatchedLane: + return_highestLanePriority = SyncBatchedLanePriority; + return SyncBatchedLane; - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - var props = { - configurable: true, - enumerable: true, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. + case InputDiscreteHydrationLane: + return_highestLanePriority = InputDiscreteHydrationLanePriority; + return InputDiscreteHydrationLane; + + case InputDiscreteLane: + return_highestLanePriority = InputDiscreteLanePriority; + return InputDiscreteLane; + + case InputContinuousHydrationLane: + return_highestLanePriority = InputContinuousHydrationLanePriority; + return InputContinuousHydrationLane; + + case InputContinuousLane: + return_highestLanePriority = InputContinuousLanePriority; + return InputContinuousLane; + + case DefaultHydrationLane: + return_highestLanePriority = DefaultHydrationLanePriority; + return DefaultHydrationLane; + + case DefaultLane: + return_highestLanePriority = DefaultLanePriority; + return DefaultLane; + + case TransitionHydrationLane: + return_highestLanePriority = TransitionHydrationPriority; + return TransitionHydrationLane; + + 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: + return_highestLanePriority = TransitionPriority; + return lanes & TransitionLanes; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + return_highestLanePriority = RetryLanePriority; + return lanes & RetryLanes; + + case SelectiveHydrationLane: + return_highestLanePriority = SelectiveHydrationLanePriority; + return SelectiveHydrationLane; + + case IdleHydrationLane: + return_highestLanePriority = IdleHydrationLanePriority; + return IdleHydrationLane; + + case IdleLane: + return_highestLanePriority = IdleLanePriority; + return IdleLane; + + case OffscreenLane: + return_highestLanePriority = OffscreenLanePriority; + return OffscreenLane; - Object.defineProperties(console, { - log: Object.assign({}, props, { - value: prevLog - }), - info: Object.assign({}, props, { - value: prevInfo - }), - warn: Object.assign({}, props, { - value: prevWarn - }), - error: Object.assign({}, props, { - value: prevError - }), - group: Object.assign({}, props, { - value: prevGroup - }), - groupCollapsed: Object.assign({}, props, { - value: prevGroupCollapsed - }), - groupEnd: Object.assign({}, props, { - value: prevGroupEnd - }) - }); - /* eslint-enable react-internal/no-production-logging */ - } + default: + { + error("Should have found matching lanes. This is a bug in React."); + } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - if (disabledDepth < 0) { - error( - "disabledDepth fell below zero. " + - "This is a bug in React. Please file an issue." - ); - } + return_highestLanePriority = DefaultLanePriority; + return lanes; } } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -function describeBuiltInComponentFrame(name, source, ownerFn) { - { - var ownerName = null; +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case ImmediatePriority: + return SyncLanePriority; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + case UserBlockingPriority: + return InputContinuousLanePriority; - return describeComponentFrame(name, source, ownerName); - } -} -var componentFrameCache; + case NormalPriority: + case LowPriority: + // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. + return DefaultLanePriority; -{ - var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap(); + case IdlePriority: + return IdleLanePriority; + + default: + return NoLanePriority; + } } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case SyncLanePriority: + case SyncBatchedLanePriority: + return ImmediatePriority; -function describeComponentFrame(name, source, ownerName) { - var sourceInfo = ""; + case InputDiscreteHydrationLanePriority: + case InputDiscreteLanePriority: + case InputContinuousHydrationLanePriority: + case InputContinuousLanePriority: + return UserBlockingPriority; - if (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: - // prefer "folder/index.js" instead of just "index.js". + case DefaultHydrationLanePriority: + case DefaultLanePriority: + case TransitionHydrationPriority: + case TransitionPriority: + case SelectiveHydrationLanePriority: + case RetryLanePriority: + return NormalPriority; - if (/^index\./.test(fileName)) { - var match = path.match(BEFORE_SLASH_RE); + case IdleHydrationLanePriority: + case IdleLanePriority: + case OffscreenLanePriority: + return IdlePriority; - if (match) { - var pathBeforeSlash = match[1]; + case NoLanePriority: + return NoPriority; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } - } + default: { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); } - - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; } - - return "\n in " + (name || "Unknown") + sourceInfo; } +function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; -function describeClassComponentFrame(ctor, source, ownerFn) { - { - return describeFunctionComponentFrame(ctor, source, ownerFn); + if (pendingLanes === NoLanes) { + return_highestLanePriority = NoLanePriority; + return NoLanes; } -} -function describeFunctionComponentFrame(fn, source, ownerFn) { - { - if (!fn) { - return ""; - } - - var name = fn.displayName || fn.name || null; - var ownerName = null; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + var nextLanes = NoLanes; + var nextLanePriority = NoLanePriority; + var expiredLanes = root.expiredLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; // Check if any work has expired. - return describeComponentFrame(name, source, ownerName); - } -} - -function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { - if (type == null) { - return ""; - } - - if (typeof type === "function") { - { - return describeFunctionComponentFrame(type, source, ownerFn); - } - } - - if (typeof type === "string") { - return describeBuiltInComponentFrame(type, source, ownerFn); - } - - switch (type) { - case REACT_SUSPENSE_TYPE: - return describeBuiltInComponentFrame("Suspense", source, ownerFn); - - case REACT_SUSPENSE_LIST_TYPE: - return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); - } + if (expiredLanes !== NoLanes) { + // TODO: Should entangle with SyncLane + nextLanes = expiredLanes; + nextLanePriority = return_highestLanePriority = SyncLanePriority; + } else { + // Do not work on any idle work until all the non-idle work has finished, + // even if the work is suspended. + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - if (typeof type === "object") { - switch (type.$$typeof) { - case REACT_FORWARD_REF_TYPE: - return describeFunctionComponentFrame(type.render, source, ownerFn); + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; - case REACT_MEMO_TYPE: - // Memo may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; - case REACT_LAZY_TYPE: { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); + nextLanePriority = return_highestLanePriority; + } + } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; - try { - // Lazy may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV( - init(payload), - source, - ownerFn - ); - } catch (x) {} + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + nextLanePriority = return_highestLanePriority; + } } } } - return ""; -} + if (nextLanes === NoLanes) { + // This should only be reachable if we're suspended + // TODO: Consider warning in this path if a fallback timer is not scheduled. + return NoLanes; + } // If we're already in the middle of a render, switching lanes will interrupt + // it and we'll lose our progress. We should only do this if the new lanes are + // higher priority. -var loggedTypeFailures = {}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + if ( + wipLanes !== NoLanes && + wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't + // bother waiting until the root is complete. + (wipLanes & suspendedLanes) === NoLanes + ) { + getHighestPriorityLanes(wipLanes); + var wipLanePriority = return_highestLanePriority; -function setCurrentlyValidatingElement(element) { - { - if (element) { - var owner = element._owner; - var stack = describeUnknownElementTypeFrameInDEV( - element.type, - element._source, - owner ? owner.type : null - ); - ReactDebugCurrentFrame.setExtraStackFrame(stack); + if ( + nextLanePriority <= wipLanePriority || // Default priority updates should not interrupt transition updates. The + // only difference between default updates and transition updates is that + // default updates do not support refresh transitions. + (nextLanePriority === DefaultLanePriority && + wipLanePriority === TransitionPriority) + ) { + // Keep working on the existing in-progress tree. Do not interrupt. + return wipLanes; } else { - ReactDebugCurrentFrame.setExtraStackFrame(null); + return_highestLanePriority = nextLanePriority; } - } -} - -function checkPropTypes(typeSpecs, values, location, componentName, element) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); - - for (var typeSpecName in typeSpecs) { - if (has(typeSpecs, typeSpecName)) { - var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - if (typeof typeSpecs[typeSpecName] !== "function") { - var err = Error( - (componentName || "React class") + - ": " + - location + - " type `" + - typeSpecName + - "` is invalid; " + - "it must be a function, usually from the `prop-types` package, but received `" + - typeof typeSpecs[typeSpecName] + - "`." + - "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." - ); - err.name = "Invariant Violation"; - throw err; - } - - error$1 = typeSpecs[typeSpecName]( - values, - typeSpecName, - componentName, - location, - null, - "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" - ); - } catch (ex) { - error$1 = ex; - } - - if (error$1 && !(error$1 instanceof Error)) { - setCurrentlyValidatingElement(element); - - error( - "%s: type specification of %s" + - " `%s` is invalid; the type checker " + - "function must return `null` or an `Error` but returned a %s. " + - "You may have forgotten to pass an argument to the type checker " + - "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + - "shape all require an argument).", - componentName || "React class", - location, - typeSpecName, - typeof error$1 - ); - - setCurrentlyValidatingElement(null); - } + } // Check for entangled lanes and add them to the batch. + // + // A lane is said to be entangled with another when it's not allowed to render + // in a batch that does not also include the other lane. Typically we do this + // when multiple updates have the same source, and we only want to respond to + // the most recent event from that source. + // + // Note that we apply entanglements *after* checking for partial work above. + // This means that if a lane is entangled during an interleaved event while + // it's already rendering, we won't interrupt it. This is intentional, since + // entanglement is usually "best effort": we'll try our best to render the + // lanes in the same batch, but it's not worth throwing out partially + // completed work in order to do it. + // TODO: Reconsider this. The counter-argument is that the partial work + // represents an intermediate state, which we don't want to show to the user. + // And by spending extra time finishing it, we're increasing the amount of + // time it takes to show the final state, which is what they are actually + // waiting for. + // + // For those exceptions where entanglement is semantically important, like + // useMutableSource, we should ensure that there is no partial work at the + // time we apply the entanglement. - if ( - error$1 instanceof Error && - !(error$1.message in loggedTypeFailures) - ) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error$1.message] = true; - setCurrentlyValidatingElement(element); + var entangledLanes = root.entangledLanes; - error("Failed %s type: %s", location, error$1.message); + if (entangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = nextLanes & entangledLanes; - setCurrentlyValidatingElement(null); - } - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + nextLanes |= entanglements[index]; + lanes &= ~lane; } } -} -var valueStack = []; -var fiberStack; - -{ - fiberStack = []; -} - -var index = -1; - -function createCursor(defaultValue) { - return { - current: defaultValue - }; + return nextLanes; } +function getMostRecentEventTime(root, lanes) { + var eventTimes = root.eventTimes; + var mostRecentEventTime = NoTimestamp; -function pop(cursor, fiber) { - if (index < 0) { - { - error("Unexpected pop."); - } - - return; - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var eventTime = eventTimes[index]; - { - if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); + if (eventTime > mostRecentEventTime) { + mostRecentEventTime = eventTime; } - } - - cursor.current = valueStack[index]; - valueStack[index] = null; - { - fiberStack[index] = null; + lanes &= ~lane; } - index--; + return mostRecentEventTime; } -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; - - { - fiberStack[index] = fiber; - } - - cursor.current = value; -} - -var warnedAboutMissingGetChildContext; +function computeExpirationTime(lane, currentTime) { + // TODO: Expiration heuristic is constant per lane, so could use a map. + getHighestPriorityLanes(lane); + var priority = return_highestLanePriority; -{ - warnedAboutMissingGetChildContext = {}; + if (priority >= InputContinuousLanePriority) { + // User interactions should expire slightly more quickly. + // + // NOTE: This is set to the corresponding constant as in Scheduler.js. When + // we made it larger, a product metric in www regressed, suggesting there's + // a user interaction that's being starved by a series of synchronous + // updates. If that theory is correct, the proper solution is to fix the + // starvation. However, this scenario supports the idea that expiration + // times are an important safeguard when starvation does happen. + // + // Also note that, in the case of user input specifically, this will soon no + // longer be an issue because we plan to make user input synchronous by + // default (until you enter `startTransition`, of course.) + // + // If weren't planning to make these updates synchronous soon anyway, I + // would probably make this number a configurable parameter. + return currentTime + 250; + } else if (priority >= TransitionPriority) { + return currentTime + 5000; + } else { + // Anything idle priority or lower should never expire. + return NoTimestamp; + } } -var emptyContextObject = {}; - -{ - Object.freeze(emptyContextObject); -} // A cursor to the current merged context object on the stack. - -var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. +function markStarvedLanesAsExpired(root, currentTime) { + // TODO: This gets called every time we yield. We can optimize by storing + // the earliest expiration time on the root. Then use that to quickly bail out + // of this function. + var pendingLanes = root.pendingLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; + var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their + // expiration time. If so, we'll assume the update is being starved and mark + // it as expired to force it to finish. -var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. -// We use this to get access to the parent context after we have already -// pushed the next context provider, and now need to merge their contexts. + var lanes = pendingLanes; -var previousContext = emptyContextObject; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; -function getUnmaskedContext( - workInProgress, - Component, - didPushOwnContextIfProvider -) { - { - if (didPushOwnContextIfProvider && isContextProvider(Component)) { - // If the fiber is a context provider itself, when we read its context - // we may have already pushed its own child context on the stack. A context - // provider should not "see" its own child context. Therefore we read the - // previous (parent) context instead for a context provider. - return previousContext; + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); + } + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; } - return contextStackCursor.current; + lanes &= ~lane; } -} +} // This returns the highest priority pending lanes regardless of whether they +function getLanesToRetrySynchronouslyOnError(root) { + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; -function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { - var instance = workInProgress.stateNode; - instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; - instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } + + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } + + return NoLanes; +} +function returnNextLanesPriority() { + return return_highestLanePriority; +} +function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; +} +function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; } +function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; +} +function isTransitionLane(lane) { + return (lane & TransitionLanes) !== 0; +} // To ensure consistency across multiple updates in the same event, this should +// be a pure function, so that it always returns the same lane for given inputs. -function getMaskedContext(workInProgress, unmaskedContext) { - { - var type = workInProgress.type; - var contextTypes = type.contextTypes; +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case NoLanePriority: + break; - if (!contextTypes) { - return emptyContextObject; - } // Avoid recreating masked context unless unmasked context has changed. - // Failing to do this will result in unnecessary calls to componentWillReceiveProps. - // This may trigger infinite loops if componentWillReceiveProps calls setState. + case SyncLanePriority: + return SyncLane; - var instance = workInProgress.stateNode; + case SyncBatchedLanePriority: + return SyncBatchedLane; - if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext - ) { - return instance.__reactInternalMemoizedMaskedChildContext; - } + case InputDiscreteLanePriority: + return InputDiscreteLane; - var context = {}; + case InputContinuousLanePriority: + return InputContinuousLane; - for (var key in contextTypes) { - context[key] = unmaskedContext[key]; - } + case DefaultLanePriority: + return DefaultLane; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); - } // Cache unmasked context so we can avoid recreating masked context unless necessary. - // Context is created before the class component is instantiated so check for instance. + case TransitionPriority: // Should be handled by findTransitionLane instead - if (instance) { - cacheContext(workInProgress, unmaskedContext, context); - } + case RetryLanePriority: + // Should be handled by findRetryLane instead + break; - return context; + case IdleLanePriority: + return IdleLane; } -} -function hasContextChanged() { { - return didPerformWorkStackCursor.current; + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); } } +function claimNextTransitionLane() { + // Cycle through the lanes, assigning each new transition to the next lane. + // In most cases, this means every transition gets its own lane, until we + // run out of lanes and cycle back to the beginning. + var lane = nextTransitionLane; + nextTransitionLane <<= 1; -function isContextProvider(type) { - { - var childContextTypes = type.childContextTypes; - return childContextTypes !== null && childContextTypes !== undefined; + if ((nextTransitionLane & TransitionLanes) === 0) { + nextTransitionLane = TransitionLane1; } + + return lane; } +function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; -function popContext(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); + if ((nextRetryLane & RetryLanes) === 0) { + nextRetryLane = RetryLane1; } + + return lane; } -function popTopLevelContextObject(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); - } +function getHighestPriorityLane(lanes) { + return lanes & -lanes; } -function pushTopLevelContextObject(fiber, context, didChange) { - { - if (!(contextStackCursor.current === emptyContextObject)) { - throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." - ); - } +function pickArbitraryLane(lanes) { + // This wrapper function gets inlined. Only exists so to communicate that it + // doesn't matter which bit is selected; you can pick any bit without + // affecting the algorithms where its used. Here I'm using + // getHighestPriorityLane because it requires the fewest operations. + return getHighestPriorityLane(lanes); +} - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); - } +function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); } -function processChildContext(fiber, type, parentContext) { - { - var instance = fiber.stateNode; - var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. - // It has only been added in Fiber to match the (unintentional) behavior in Stack. +function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); +} - if (typeof instance.getChildContext !== "function") { - { - var componentName = getComponentName(type) || "Unknown"; +function includesSomeLane(a, b) { + return (a & b) !== NoLanes; +} +function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; +} +function mergeLanes(a, b) { + return a | b; +} +function removeLanes(set, subset) { + return set & ~subset; +} +function intersectLanes(a, b) { + return a & b; +} // Seems redundant, but it changes the type from a single lane (used for +// updates) to a group of lanes (used for flushing work). - if (!warnedAboutMissingGetChildContext[componentName]) { - warnedAboutMissingGetChildContext[componentName] = true; +function laneToLanes(lane) { + return lane; +} +function createLaneMap(initial) { + // Intentionally pushing one by one. + // https://v8.dev/blog/elements-kinds#avoid-creating-holes + var laneMap = []; - error( - "%s.childContextTypes is specified but there is no getChildContext() method " + - "on the instance. You can either define getChildContext() on %s or remove " + - "childContextTypes from it.", - componentName, - componentName - ); - } - } + for (var i = 0; i < TotalLanes; i++) { + laneMap.push(initial); + } - return parentContext; - } - - var childContext = instance.getChildContext(); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update + // could unblock them. Clear the suspended lanes so that we can try rendering + // them again. + // + // TODO: We really only need to unsuspend only lanes that are in the + // `subtreeLanes` of the updated fiber, or the update lanes of the return + // path. This would exclude suspended updates in an unrelated sibling tree, + // since there's no way for this update to unblock it. + // + // We don't do this if the incoming update is idle, because we never process + // idle updates until after all the regular updates have finished; there's no + // way it could unblock a transition. - for (var contextKey in childContext) { - if (!(contextKey in childContextTypes)) { - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' - ); - } - } + if (updateLane !== IdleLane) { + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; + } - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); - } + var eventTimes = root.eventTimes; + var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most + // recent event, and we assume time is monotonically increasing. - return Object.assign({}, parentContext, childContext); - } + eventTimes[index] = eventTime; } +function markRootSuspended(root, suspendedLanes) { + root.suspendedLanes |= suspendedLanes; + root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. -function pushContextProvider(workInProgress) { - { - var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. - // If the instance does not exist yet, we will push null at first, - // and replace it on the stack later when invalidating the context. - - var memoizedMergedChildContext = - (instance && instance.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; // Remember the parent context so we can merge with it later. - // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + var expirationTimes = root.expirationTimes; + var lanes = suspendedLanes; - previousContext = contextStackCursor.current; - push(contextStackCursor, memoizedMergedChildContext, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); - return true; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } +function markRootPinged(root, pingedLanes, eventTime) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; +} +function markRootExpired(root, expiredLanes) { + root.expiredLanes |= expiredLanes & root.pendingLanes; +} +function hasDiscreteLanes(lanes) { + return (lanes & InputDiscreteLane) !== NoLanes; +} +function markRootMutableRead(root, updateLane) { + root.mutableReadLanes |= updateLane & root.pendingLanes; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again -function invalidateContextProvider(workInProgress, type, didChange) { - { - var instance = workInProgress.stateNode; - - if (!instance) { - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); - } + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; - if (didChange) { - // Merge parent and own context. - // Skip this if we're not updating due to sCU. - // This avoids unnecessarily recomputing memoized values. - var mergedContext = processChildContext( - workInProgress, - type, - previousContext - ); - instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. - // It is important to unwind the context in the reverse order. + var entanglements = root.entanglements; + var eventTimes = root.eventTimes; + var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work - pop(didPerformWorkStackCursor, workInProgress); - pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + var lanes = noLongerPendingLanes; - push(contextStackCursor, mergedContext, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } else { - pop(didPerformWorkStackCursor, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + eventTimes[index] = NoTimestamp; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } +function markRootEntangled(root, entangledLanes) { + // In addition to entangling each of the given lanes with each other, we also + // have to consider _transitive_ entanglements. For each lane that is already + // entangled with *any* of the given lanes, that lane is now transitively + // entangled with *all* the given lanes. + // + // Translated: If C is entangled with A, then entangling A with B also + // entangles C with B. + // + // If this is hard to grasp, it might help to intentionally break this + // function and look at the tests that fail in ReactTransition-test.js. Try + // commenting out one of the conditions below. + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + var entanglements = root.entanglements; + var lanes = rootEntangledLanes; -function findCurrentUnmaskedContext(fiber) { - { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw Error( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." - ); - } - - var node = fiber; - - do { - switch (node.tag) { - case HostRoot: - return node.stateNode.context; - - case ClassComponent: { - var Component = node.type; - - if (isContextProvider(Component)) { - return node.stateNode.__reactInternalMemoizedMergedChildContext; - } - - break; - } - } - - node = node.return; - } while (node !== null); + while (lanes) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; - { - throw Error( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); + if ( + // Is this one of the newly entangled lanes? + (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? + (entanglements[index] & entangledLanes) + ) { + entanglements[index] |= entangledLanes; } + + lanes &= ~lane; } } +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. +// Based on: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -var LegacyRoot = 0; -var BlockingRoot = 1; -var ConcurrentRoot = 2; +var log = Math.log; +var LN2 = Math.LN2; -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; +function clz32Fallback(lanes) { + if (lanes === 0) { + return 32; } - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + return (31 - ((log(lanes) / LN2) | 0)) | 0; +} - if (hook.isDisabled) { - // This isn't a real property on the hook, but it can be set to opt out - // of DevTools integration and associated warnings and logs. - // https://github.com/facebook/react/issues/3877 - return true; +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_now$1 = Scheduler.unstable_now; + +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); } +} +var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. - if (!hook.supportsFiber) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. +// can re-export everything from this module. - return true; +function shim() { + { + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); } +} // Mutation (when unsupported) - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. +var supportsMutation = false; +var commitMount = shim; +var clearContainer = shim; - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists +// can re-export everything from this module. - return true; -} -function onScheduleRoot(root, children) { +function shim$1() { { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } + throw Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ); } -} -function onCommitRoot(root, priorityLevel) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; +} // Hydration (when unsupported) +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var hydrateTextInstance = shim$1; - if (enableProfilerTimer) { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, + cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout; +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. +// This means that they never overlap. - error("React instrumentation encountered an error: %s", err); - } - } - } - } -} -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; +var nextReactTag = 2; - error("React instrumentation encountered an error: %s", err); - } - } - } - } +// TODO: Remove this conditional once all changes have propagated. +if (registerEventHandler) { + /** + * Register the event emitter with the native bridge + */ + registerEventHandler(dispatchEvent); } +/** + * This is used for refs on host components. + */ -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_now = Scheduler.unstable_now; - -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) +var ReactFabricHostComponent = /*#__PURE__*/ (function() { + function ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); - } -} -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. - -var ImmediatePriority = 99; -var UserBlockingPriority = 98; -var NormalPriority = 97; -var LowPriority = 96; -var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - -var NoPriority = 90; -var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. - -var SyncLanePriority = 15; -var SyncBatchedLanePriority = 14; -var InputDiscreteHydrationLanePriority = 13; -var InputDiscreteLanePriority = 12; -var InputContinuousHydrationLanePriority = 11; -var InputContinuousLanePriority = 10; -var DefaultHydrationLanePriority = 9; -var DefaultLanePriority = 8; -var TransitionHydrationPriority = 7; -var TransitionPriority = 6; -var RetryLanePriority = 5; -var SelectiveHydrationLanePriority = 4; -var IdleHydrationLanePriority = 3; -var IdleLanePriority = 2; -var OffscreenLanePriority = 1; -var NoLanePriority = 0; -var TotalLanes = 31; -var NoLanes = - /* */ - 0; -var NoLane = - /* */ - 0; -var SyncLane = - /* */ - 1; -var SyncBatchedLane = - /* */ - 2; -var InputDiscreteHydrationLane = - /* */ - 4; -var InputDiscreteLanes = - /* */ - 24; -var InputContinuousHydrationLane = - /* */ - 32; -var InputContinuousLanes = - /* */ - 192; -var DefaultHydrationLane = - /* */ - 256; -var DefaultLanes = - /* */ - 3584; -var TransitionHydrationLane = - /* */ - 4096; -var TransitionLanes = - /* */ - 4186112; -var RetryLanes = - /* */ - 62914560; -var SomeRetryLane = - /* */ - 33554432; -var SelectiveHydrationLane = - /* */ - 67108864; -var NonIdleLanes = - /* */ - 134217727; -var IdleHydrationLane = - /* */ - 134217728; -var IdleLanes = - /* */ - 805306368; -var OffscreenLane = - /* */ - 1073741824; -var NoTimestamp = -1; -// Used by getHighestPriorityLanes and getNextLanes: - -var return_highestLanePriority = DefaultLanePriority; - -function getHighestPriorityLanes(lanes) { - if ((SyncLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncLanePriority; - return SyncLane; - } - - if ((SyncBatchedLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncBatchedLanePriority; - return SyncBatchedLane; - } - - if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { - return_highestLanePriority = InputDiscreteHydrationLanePriority; - return InputDiscreteHydrationLane; - } - - var inputDiscreteLanes = InputDiscreteLanes & lanes; - - if (inputDiscreteLanes !== NoLanes) { - return_highestLanePriority = InputDiscreteLanePriority; - return inputDiscreteLanes; + this._nativeTag = tag; + this.viewConfig = viewConfig; + this.currentProps = props; + this._internalInstanceHandle = internalInstanceHandle; } - if ((lanes & InputContinuousHydrationLane) !== NoLanes) { - return_highestLanePriority = InputContinuousHydrationLanePriority; - return InputContinuousHydrationLane; - } + var _proto = ReactFabricHostComponent.prototype; - var inputContinuousLanes = InputContinuousLanes & lanes; + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; - if (inputContinuousLanes !== NoLanes) { - return_highestLanePriority = InputContinuousLanePriority; - return inputContinuousLanes; - } + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; - if ((lanes & DefaultHydrationLane) !== NoLanes) { - return_highestLanePriority = DefaultHydrationLanePriority; - return DefaultHydrationLane; - } + _proto.measure = function measure(callback) { + fabricMeasure( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; - var defaultLanes = DefaultLanes & lanes; + _proto.measureInWindow = function measureInWindow(callback) { + fabricMeasureInWindow( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; - if (defaultLanes !== NoLanes) { - return_highestLanePriority = DefaultLanePriority; - return defaultLanes; - } + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) /* currently unused */ + { + if ( + typeof relativeToNativeNode === "number" || + !(relativeToNativeNode instanceof ReactFabricHostComponent) + ) { + { + error( + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + } - if ((lanes & TransitionHydrationLane) !== NoLanes) { - return_highestLanePriority = TransitionHydrationPriority; - return TransitionHydrationLane; - } + return; + } - var transitionLanes = TransitionLanes & lanes; + fabricMeasureLayout( + this._internalInstanceHandle.stateNode.node, + relativeToNativeNode._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; - if (transitionLanes !== NoLanes) { - return_highestLanePriority = TransitionPriority; - return transitionLanes; - } + _proto.setNativeProps = function setNativeProps(nativeProps) { + { + error("Warning: setNativeProps is not currently supported in Fabric"); + } - var retryLanes = RetryLanes & lanes; + return; + }; - if (retryLanes !== NoLanes) { - return_highestLanePriority = RetryLanePriority; - return retryLanes; - } + return ReactFabricHostComponent; +})(); // eslint-disable-next-line no-unused-expressions +function appendInitialChild(parentInstance, child) { + appendChildNode(parentInstance.node, child.node); +} +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + var tag = nextReactTag; + nextReactTag += 2; + var viewConfig = getViewConfigForType(type); - if (lanes & SelectiveHydrationLane) { - return_highestLanePriority = SelectiveHydrationLanePriority; - return SelectiveHydrationLane; + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] + ); + } + } } - if ((lanes & IdleHydrationLane) !== NoLanes) { - return_highestLanePriority = IdleHydrationLanePriority; - return IdleHydrationLane; - } - - var idleLanes = IdleLanes & lanes; - - if (idleLanes !== NoLanes) { - return_highestLanePriority = IdleLanePriority; - return idleLanes; - } - - if ((OffscreenLane & lanes) !== NoLanes) { - return_highestLanePriority = OffscreenLanePriority; - return OffscreenLane; + var updatePayload = create(props, viewConfig.validAttributes); + var node = createNode( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload, // props + internalInstanceHandle // internalInstanceHandle + ); + var component = new ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle + ); + return { + node: node, + canonical: component + }; +} +function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + if (!hostContext.isInAParentText) { + throw Error("Text strings must be rendered within a component."); } - { - error("Should have found matching lanes. This is a bug in React."); - } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - - return_highestLanePriority = DefaultLanePriority; - return lanes; + var tag = nextReactTag; + nextReactTag += 2; + var node = createNode( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag + { + text: text + }, // props + internalInstanceHandle // instance handle + ); + return { + node: node + }; } +function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; +} +function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case ImmediatePriority: - return SyncLanePriority; - - case UserBlockingPriority: - return InputContinuousLanePriority; - - case NormalPriority: - case LowPriority: - // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. - return DefaultLanePriority; + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText + }; + } else { + return parentHostContext; + } +} +function getPublicInstance(instance) { + return instance.canonical; +} +function prepareForCommit(containerInfo) { + // Noop + return null; +} +function prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + hostContext +) { + var viewConfig = instance.canonical.viewConfig; + var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // TODO: If the event handlers have changed, we need to update the current props + // in the commit phase but there is no host config hook to do it yet. + // So instead we hack it by updating it in the render phase. - case IdlePriority: - return IdleLanePriority; + instance.canonical.currentProps = newProps; + return updatePayload; +} +function resetAfterCommit(containerInfo) { + // Noop +} +function shouldSetTextContent(type, props) { + // TODO (bvaughn) Revisit this decision. + // Always returning false simplifies the createInstance() implementation, + // But creates an additional child Fiber for raw text children. + // No additional native views are created though. + // It's not clear to me which is better so I'm deferring for now. + // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 + return false; +} +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; // ------------------- +function cloneInstance( + instance, + updatePayload, + type, + oldProps, + newProps, + internalInstanceHandle, + keepChildren, + recyclableInstance +) { + var node = instance.node; + var clone; - default: - return NoLanePriority; + if (keepChildren) { + if (updatePayload !== null) { + clone = cloneNodeWithNewProps(node, updatePayload); + } else { + clone = cloneNode(node); + } + } else { + if (updatePayload !== null) { + clone = cloneNodeWithNewChildrenAndProps(node, updatePayload); + } else { + clone = cloneNodeWithNewChildren(node); + } } + + return { + node: clone, + canonical: instance.canonical + }; +} +function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { + var viewConfig = instance.canonical.viewConfig; + var node = instance.node; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes + ); + return { + node: cloneNodeWithNewProps(node, updatePayload), + canonical: instance.canonical + }; +} +function cloneHiddenTextInstance(instance, text, internalInstanceHandle) { + throw new Error("Not yet implemented."); +} +function createContainerChildSet(container) { + return createChildNodeSet(container); +} +function appendChildToContainerChildSet(childSet, child) { + appendChildNodeToSet(childSet, child.node); +} +function finalizeContainerChildren(container, newChildren) { + completeRoot(container, newChildren); +} +function makeClientIdInDEV(warnOnAccessInDEV) { + throw new Error("Not yet implemented"); +} +function preparePortalMount(portalInstance) { + // noop } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case SyncLanePriority: - case SyncBatchedLanePriority: - return ImmediatePriority; - case InputDiscreteHydrationLanePriority: - case InputDiscreteLanePriority: - case InputContinuousHydrationLanePriority: - case InputContinuousLanePriority: - return UserBlockingPriority; +// Helpers to patch console.logs to avoid logging during side-effect free +// replaying on render function. This currently only patches the object +// lazily which won't cover if the log function was extracted eagerly. +// We could also eagerly patch the method. +var disabledDepth = 0; +var prevLog; +var prevInfo; +var prevWarn; +var prevError; +var prevGroup; +var prevGroupCollapsed; +var prevGroupEnd; - case DefaultHydrationLanePriority: - case DefaultLanePriority: - case TransitionHydrationPriority: - case TransitionPriority: - case SelectiveHydrationLanePriority: - case RetryLanePriority: - return NormalPriority; +function disabledLog() {} - case IdleHydrationLanePriority: - case IdleLanePriority: - case OffscreenLanePriority: - return IdlePriority; +disabledLog.__reactDisabledLog = true; +function disableLogs() { + { + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 - case NoLanePriority: - return NoPriority; + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. - default: { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + /* eslint-enable react-internal/no-production-logging */ } + + disabledDepth++; } } -function getNextLanes(root, wipLanes) { - // Early bailout if there's no pending work left. - var pendingLanes = root.pendingLanes; +function reenableLogs() { + { + disabledDepth--; - if (pendingLanes === NoLanes) { - return_highestLanePriority = NoLanePriority; - return NoLanes; + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + var props = { + configurable: true, + enumerable: true, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. + + Object.defineProperties(console, { + log: Object.assign({}, props, { + value: prevLog + }), + info: Object.assign({}, props, { + value: prevInfo + }), + warn: Object.assign({}, props, { + value: prevWarn + }), + error: Object.assign({}, props, { + value: prevError + }), + group: Object.assign({}, props, { + value: prevGroup + }), + groupCollapsed: Object.assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: Object.assign({}, props, { + value: prevGroupEnd + }) + }); + /* eslint-enable react-internal/no-production-logging */ + } + + if (disabledDepth < 0) { + error( + "disabledDepth fell below zero. " + + "This is a bug in React. Please file an issue." + ); + } } +} - var nextLanes = NoLanes; - var nextLanePriority = NoLanePriority; - var expiredLanes = root.expiredLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; // Check if any work has expired. +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +function describeBuiltInComponentFrame(name, source, ownerFn) { + { + var ownerName = null; - if (expiredLanes !== NoLanes) { - nextLanes = expiredLanes; - nextLanePriority = return_highestLanePriority = SyncLanePriority; - } else { - // Do not work on any idle work until all the non-idle work has finished, - // even if the work is suspended. - var nonIdlePendingLanes = pendingLanes & NonIdleLanes; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - if (nonIdlePendingLanes !== NoLanes) { - var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + return describeComponentFrame(name, source, ownerName); + } +} +var componentFrameCache; - if (nonIdleUnblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; +{ + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; - if (nonIdlePingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } else { - // The only remaining work is Idle. - var unblockedLanes = pendingLanes & ~suspendedLanes; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; - if (unblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(unblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - if (pingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(pingedLanes); - nextLanePriority = return_highestLanePriority; + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: + // prefer "folder/index.js" instead of just "index.js". + + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); + + if (match) { + var pathBeforeSlash = match[1]; + + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; } } } + + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } - if (nextLanes === NoLanes) { - // This should only be reachable if we're suspended - // TODO: Consider warning in this path if a fallback timer is not scheduled. - return NoLanes; - } // If there are higher priority lanes, we'll include them even if they - // are suspended. + return "\n in " + (name || "Unknown") + sourceInfo; +} - nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt - // it and we'll lose our progress. We should only do this if the new lanes are - // higher priority. +function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeFunctionComponentFrame(ctor, source, ownerFn); + } +} +function describeFunctionComponentFrame(fn, source, ownerFn) { + { + if (!fn) { + return ""; + } - if ( - wipLanes !== NoLanes && - wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't - // bother waiting until the root is complete. - (wipLanes & suspendedLanes) === NoLanes - ) { - getHighestPriorityLanes(wipLanes); - var wipLanePriority = return_highestLanePriority; + var name = fn.displayName || fn.name || null; + var ownerName = null; - if (nextLanePriority <= wipLanePriority) { - return wipLanes; - } else { - return_highestLanePriority = nextLanePriority; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; } - } // Check for entangled lanes and add them to the batch. - // - // A lane is said to be entangled with another when it's not allowed to render - // in a batch that does not also include the other lane. Typically we do this - // when multiple updates have the same source, and we only want to respond to - // the most recent event from that source. - // - // Note that we apply entanglements *after* checking for partial work above. - // This means that if a lane is entangled during an interleaved event while - // it's already rendering, we won't interrupt it. This is intentional, since - // entanglement is usually "best effort": we'll try our best to render the - // lanes in the same batch, but it's not worth throwing out partially - // completed work in order to do it. - // - // For those exceptions where entanglement is semantically important, like - // useMutableSource, we should ensure that there is no partial work at the - // time we apply the entanglement. - var entangledLanes = root.entangledLanes; + return describeComponentFrame(name, source, ownerName); + } +} - if (entangledLanes !== NoLanes) { - var entanglements = root.entanglements; - var lanes = nextLanes & entangledLanes; +function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - nextLanes |= entanglements[index]; - lanes &= ~lane; + if (typeof type === "function") { + { + return describeFunctionComponentFrame(type, source, ownerFn); } } - return nextLanes; -} -function getMostRecentEventTime(root, lanes) { - var eventTimes = root.eventTimes; - var mostRecentEventTime = NoTimestamp; + if (typeof type === "string") { + return describeBuiltInComponentFrame(type, source, ownerFn); + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var eventTime = eventTimes[index]; + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense", source, ownerFn); - if (eventTime > mostRecentEventTime) { - mostRecentEventTime = eventTime; - } + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); + } - lanes &= ~lane; + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render, source, ownerFn); + + case REACT_MEMO_TYPE: + // Memo may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + + try { + // Lazy may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV( + init(payload), + source, + ownerFn + ); + } catch (x) {} + } + } } - return mostRecentEventTime; + return ""; } -function computeExpirationTime(lane, currentTime) { - // TODO: Expiration heuristic is constant per lane, so could use a map. - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; +var loggedTypeFailures = {}; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - if (priority >= InputContinuousLanePriority) { - // User interactions should expire slightly more quickly. - // - // NOTE: This is set to the corresponding constant as in Scheduler.js. When - // we made it larger, a product metric in www regressed, suggesting there's - // a user interaction that's being starved by a series of synchronous - // updates. If that theory is correct, the proper solution is to fix the - // starvation. However, this scenario supports the idea that expiration - // times are an important safeguard when starvation does happen. - // - // Also note that, in the case of user input specifically, this will soon no - // longer be an issue because we plan to make user input synchronous by - // default (until you enter `startTransition`, of course.) - // - // If weren't planning to make these updates synchronous soon anyway, I - // would probably make this number a configurable parameter. - return currentTime + 250; - } else if (priority >= TransitionPriority) { - return currentTime + 5000; - } else { - // Anything idle priority or lower should never expire. - return NoTimestamp; - } -} - -function markStarvedLanesAsExpired(root, currentTime) { - // TODO: This gets called every time we yield. We can optimize by storing - // the earliest expiration time on the root. Then use that to quickly bail out - // of this function. - var pendingLanes = root.pendingLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; - var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their - // expiration time. If so, we'll assume the update is being starved and mark - // it as expired to force it to finish. - - var lanes = pendingLanes; - - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var expirationTime = expirationTimes[index]; - - if (expirationTime === NoTimestamp) { - // Found a pending lane with no expiration time. If it's not suspended, or - // if it's pinged, assume it's CPU-bound. Compute a new expiration time - // using the current time. - if ( - (lane & suspendedLanes) === NoLanes || - (lane & pingedLanes) !== NoLanes - ) { - // Assumes timestamps are monotonically increasing. - expirationTimes[index] = computeExpirationTime(lane, currentTime); - } - } else if (expirationTime <= currentTime) { - // This lane expired - root.expiredLanes |= lane; +function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV( + element.type, + element._source, + owner ? owner.type : null + ); + ReactDebugCurrentFrame.setExtraStackFrame(stack); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); } - - lanes &= ~lane; - } -} // This returns the highest priority pending lanes regardless of whether they -function getLanesToRetrySynchronouslyOnError(root) { - var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - - if (everythingButOffscreen !== NoLanes) { - return everythingButOffscreen; } - - if (everythingButOffscreen & OffscreenLane) { - return OffscreenLane; - } - - return NoLanes; -} -function returnNextLanesPriority() { - return return_highestLanePriority; -} -function includesNonIdleWork(lanes) { - return (lanes & NonIdleLanes) !== NoLanes; } -function includesOnlyRetries(lanes) { - return (lanes & RetryLanes) === lanes; -} -function includesOnlyTransitions(lanes) { - return (lanes & TransitionLanes) === lanes; -} // To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. - -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case NoLanePriority: - break; - - case SyncLanePriority: - return SyncLane; - case SyncBatchedLanePriority: - return SyncBatchedLane; +function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(Object.prototype.hasOwnProperty); - case InputDiscreteLanePriority: { - var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. - if (_lane === NoLane) { - // Shift to the next priority level - return findUpdateLane(InputContinuousLanePriority, wipLanes); - } + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error( + (componentName || "React class") + + ": " + + location + + " type `" + + typeSpecName + + "` is invalid; " + + "it must be a function, usually from the `prop-types` package, but received `" + + typeof typeSpecs[typeSpecName] + + "`." + + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." + ); + err.name = "Invariant Violation"; + throw err; + } - return _lane; - } + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - case InputContinuousLanePriority: { - var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); - if (_lane2 === NoLane) { - // Shift to the next priority level - return findUpdateLane(DefaultLanePriority, wipLanes); - } + error( + "%s: type specification of %s" + + " `%s` is invalid; the type checker " + + "function must return `null` or an `Error` but returned a %s. " + + "You may have forgotten to pass an argument to the type checker " + + "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + + "shape all require an argument).", + componentName || "React class", + location, + typeSpecName, + typeof error$1 + ); - return _lane2; - } + setCurrentlyValidatingElement(null); + } - case DefaultLanePriority: { - var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); - if (_lane3 === NoLane) { - // If all the default lanes are already being worked on, look for a - // lane in the transition range. - _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); + error("Failed %s type: %s", location, error$1.message); - if (_lane3 === NoLane) { - // All the transition lanes are taken, too. This should be very - // rare, but as a last resort, pick a default lane. This will have - // the effect of interrupting the current work-in-progress render. - _lane3 = pickArbitraryLane(DefaultLanes); + setCurrentlyValidatingElement(null); } } - - return _lane3; } + } +} - case TransitionPriority: // Should be handled by findTransitionLane instead +var valueStack = []; +var fiberStack; - case RetryLanePriority: - // Should be handled by findRetryLane instead - break; +{ + fiberStack = []; +} - case IdleLanePriority: - var lane = pickArbitraryLane(IdleLanes & ~wipLanes); +var index = -1; - if (lane === NoLane) { - lane = pickArbitraryLane(IdleLanes); - } +function createCursor(defaultValue) { + return { + current: defaultValue + }; +} + +function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); + } - return lane; + return; } { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } } -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. - -function findTransitionLane(wipLanes, pendingLanes) { - // First look for lanes that are completely unclaimed, i.e. have no - // pending work. - var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); - if (lane === NoLane) { - // If all lanes have pending work, look for a lane that isn't currently - // being worked on. - lane = pickArbitraryLane(TransitionLanes & ~wipLanes); + cursor.current = valueStack[index]; + valueStack[index] = null; - if (lane === NoLane) { - // If everything is being worked on, pick any lane. This has the - // effect of interrupting the current work-in-progress. - lane = pickArbitraryLane(TransitionLanes); - } + { + fiberStack[index] = null; } - return lane; -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. + index--; +} -function findRetryLane(wipLanes) { - // This is a fork of `findUpdateLane` designed specifically for Suspense - // "retries" — a special update that attempts to flip a Suspense boundary - // from its placeholder state to its primary/resolved state. - var lane = pickArbitraryLane(RetryLanes & ~wipLanes); +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; - if (lane === NoLane) { - lane = pickArbitraryLane(RetryLanes); + { + fiberStack[index] = fiber; } - return lane; + cursor.current = value; } -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} +var warnedAboutMissingGetChildContext; -function getLowestPriorityLane(lanes) { - // This finds the most significant non-zero bit. - var index = 31 - clz32(lanes); - return index < 0 ? NoLanes : 1 << index; +{ + warnedAboutMissingGetChildContext = {}; } -function getEqualOrHigherPriorityLanes(lanes) { - return (getLowestPriorityLane(lanes) << 1) - 1; -} +var emptyContextObject = {}; -function pickArbitraryLane(lanes) { - // This wrapper function gets inlined. Only exists so to communicate that it - // doesn't matter which bit is selected; you can pick any bit without - // affecting the algorithms where its used. Here I'm using - // getHighestPriorityLane because it requires the fewest operations. - return getHighestPriorityLane(lanes); -} +{ + Object.freeze(emptyContextObject); +} // A cursor to the current merged context object on the stack. -function pickArbitraryLaneIndex(lanes) { - return 31 - clz32(lanes); -} +var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. -function laneToIndex(lane) { - return pickArbitraryLaneIndex(lane); -} +var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. +// We use this to get access to the parent context after we have already +// pushed the next context provider, and now need to merge their contexts. -function includesSomeLane(a, b) { - return (a & b) !== NoLanes; -} -function isSubsetOfLanes(set, subset) { - return (set & subset) === subset; -} -function mergeLanes(a, b) { - return a | b; -} -function removeLanes(set, subset) { - return set & ~subset; -} // Seems redundant, but it changes the type from a single lane (used for -// updates) to a group of lanes (used for flushing work). +var previousContext = emptyContextObject; -function laneToLanes(lane) { - return lane; -} -function createLaneMap(initial) { - // Intentionally pushing one by one. - // https://v8.dev/blog/elements-kinds#avoid-creating-holes - var laneMap = []; +function getUnmaskedContext( + workInProgress, + Component, + didPushOwnContextIfProvider +) { + { + if (didPushOwnContextIfProvider && isContextProvider(Component)) { + // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; + } - for (var i = 0; i < TotalLanes; i++) { - laneMap.push(initial); + return contextStackCursor.current; } - - return laneMap; } -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But - // it's not practical to try every single possible combination. We need a - // heuristic to decide which lanes to attempt to render, and in which batches. - // For now, we use the same heuristic as in the old ExpirationTimes model: - // retry any lane at equal or lower priority, but don't try updates at higher - // priority without also including the lower priority updates. This works well - // when considering updates across different priority levels, but isn't - // sufficient for updates within the same priority, since we want to treat - // those updates as parallel. - // Unsuspend any update at equal or lower priority. - - var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 - - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - var eventTimes = root.eventTimes; - var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most - // recent event, and we assume time is monotonically increasing. - eventTimes[index] = eventTime; +function cacheContext(workInProgress, unmaskedContext, maskedContext) { + { + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + } } -function markRootSuspended(root, suspendedLanes) { - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. - var expirationTimes = root.expirationTimes; - var lanes = suspendedLanes; +function getMaskedContext(workInProgress, unmaskedContext) { + { + var type = workInProgress.type; + var contextTypes = type.contextTypes; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } -} -function markRootPinged(root, pingedLanes, eventTime) { - root.pingedLanes |= root.suspendedLanes & pingedLanes; -} -function hasDiscreteLanes(lanes) { - return (lanes & InputDiscreteLanes) !== NoLanes; -} -function markRootMutableRead(root, updateLane) { - root.mutableReadLanes |= updateLane & root.pendingLanes; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; // Let's try everything again + if (!contextTypes) { + return emptyContextObject; + } // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - var entanglements = root.entanglements; - var eventTimes = root.eventTimes; - var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work + var instance = workInProgress.stateNode; - var lanes = noLongerPendingLanes; + if ( + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + ) { + return instance.__reactInternalMemoizedMaskedChildContext; + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] = NoLanes; - eventTimes[index] = NoTimestamp; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; + var context = {}; + + for (var key in contextTypes) { + context[key] = unmaskedContext[key]; + } + + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + // Context is created before the class component is instantiated so check for instance. + + if (instance) { + cacheContext(workInProgress, unmaskedContext, context); + } + + return context; } } -function markRootEntangled(root, entangledLanes) { - root.entangledLanes |= entangledLanes; - var entanglements = root.entanglements; - var lanes = entangledLanes; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] |= entangledLanes; - lanes &= ~lane; +function hasContextChanged() { + { + return didPerformWorkStackCursor.current; } } -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. -// Based on: -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -var log = Math.log; -var LN2 = Math.LN2; +function isContextProvider(type) { + { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; + } +} -function clz32Fallback(lanes) { - if (lanes === 0) { - return 32; +function popContext(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } +} - return (31 - ((log(lanes) / LN2) | 0)) | 0; +function popTopLevelContextObject(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } } -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +function pushTopLevelContextObject(fiber, context, didChange) { + { + if (!(contextStackCursor.current === emptyContextObject)) { + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); + } -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } } -var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. - -var ImmediatePriority$1 = 99; -var UserBlockingPriority$1 = 98; -var NormalPriority$1 = 97; -var LowPriority$1 = 96; -var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. +function processChildContext(fiber, type, parentContext) { + { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. -var NoPriority$1 = 90; -var shouldYield = Scheduler_shouldYield; -var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. - Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; -var syncQueue = null; -var immediateQueueCallbackNode = null; -var isFlushingSyncQueue = false; -var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// This will be the case for modern browsers that support `performance.now`. In -// older browsers, Scheduler falls back to `Date.now`, which returns a Unix -// timestamp. In that case, subtract the module initialization time to simulate -// the behavior of performance.now and keep our times small enough to fit -// within 32 bits. -// TODO: Consider lifting this into Scheduler. + if (typeof instance.getChildContext !== "function") { + { + var componentName = getComponentName(type) || "Unknown"; -var now = - initialTimeMs$1 < 10000 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return ImmediatePriority$1; + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; - case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; + error( + "%s.childContextTypes is specified but there is no getChildContext() method " + + "on the instance. You can either define getChildContext() on %s or remove " + + "childContextTypes from it.", + componentName, + componentName + ); + } + } - case Scheduler_NormalPriority: - return NormalPriority$1; + return parentContext; + } - case Scheduler_LowPriority: - return LowPriority$1; + var childContext = instance.getChildContext(); - case Scheduler_IdlePriority: - return IdlePriority$1; + for (var contextKey in childContext) { + if (!(contextKey in childContextTypes)) { + throw Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); + } + } - default: { - throw Error("Unknown priority level."); + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); } + + return Object.assign({}, parentContext, childContext); } } -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case ImmediatePriority$1: - return Scheduler_ImmediatePriority; +function pushContextProvider(workInProgress) { + { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. - case UserBlockingPriority$1: - return Scheduler_UserBlockingPriority; + var memoizedMergedChildContext = + (instance && instance.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. - case NormalPriority$1: - return Scheduler_NormalPriority; + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); + return true; + } +} - case LowPriority$1: - return Scheduler_LowPriority; +function invalidateContextProvider(workInProgress, type, didChange) { + { + var instance = workInProgress.stateNode; - case IdlePriority$1: - return Scheduler_IdlePriority; + if (!instance) { + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); + } - default: { - throw Error("Unknown priority level."); + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext( + workInProgress, + type, + previousContext + ); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. + + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } } } -function runWithPriority(reactPriorityLevel, fn) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(priorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(priorityLevel, callback, options); -} -function scheduleSyncCallback(callback) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushSyncCallbackQueue`. - if (syncQueue === null) { - syncQueue = [callback]; // Flush the queue in the next tick, at the earliest. +function findCurrentUnmaskedContext(fiber) { + { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ); + } - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ); - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - syncQueue.push(callback); - } + var node = fiber; - return fakeCallbackNode; -} -function cancelCallback(callbackNode) { - if (callbackNode !== fakeCallbackNode) { - Scheduler_cancelCallback(callbackNode); + do { + switch (node.tag) { + case HostRoot: + return node.stateNode.context; + + case ClassComponent: { + var Component = node.type; + + if (isContextProvider(Component)) { + return node.stateNode.__reactInternalMemoizedMergedChildContext; + } + + break; + } + } + + node = node.return; + } while (node !== null); + + { + throw Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ); + } } } -function flushSyncCallbackQueue() { - if (immediateQueueCallbackNode !== null) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); + +var LegacyRoot = 0; +var BlockingRoot = 1; +var ConcurrentRoot = 2; + +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; } - flushSyncCallbackQueueImpl(); -} + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && syncQueue !== null) { - // Prevent re-entrancy. - isFlushingSyncQueue = true; - var i = 0; + if (hook.isDisabled) { + // This isn't a real property on the hook, but it can be set to opt out + // of DevTools integration and associated warnings and logs. + // https://github.com/facebook/react/issues/3877 + return true; + } + if (!hook.supportsFiber) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. + + return true; + } + + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists + + return true; +} +function onScheduleRoot(root, children) { + { + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { try { - var _isSync2 = true; - var _queue = syncQueue; - runWithPriority(ImmediatePriority$1, function() { - for (; i < _queue.length; i++) { - var callback = _queue[i]; + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; - do { - callback = callback(_isSync2); - } while (callback !== null); - } - }); - syncQueue = null; - } catch (error) { - // If something throws, leave the remaining callbacks on the queue. - if (syncQueue !== null) { - syncQueue = syncQueue.slice(i + 1); - } // Resume flushing in the next tick + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onCommitRoot(root, priorityLevel) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue + if (enableProfilerTimer) { + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + didError ); - throw error; - } finally { - isFlushingSyncQueue = false; + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } } } +var NoFlags$1 = + /* */ + 0; // Represents whether effect should fire. + +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + +var Layout = + /* */ + 2; +var Passive$1 = + /* */ + 4; + // TODO: this is special because it gets imported during build. -var ReactVersion = "17.0.1-454c2211c"; +// +// TODO: 17.0.2 has not been released to NPM; +// It exists as a placeholder so that DevTools can support work tag changes between releases. +// When we next publish a release (either 17.0.2 or 17.1.0), update the matching TODO in backend/renderer.js +var ReactVersion = "17.0.2"; -var NoMode = 0; -var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root -// tag instead +var NoMode = + /* */ + 0; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root tag instead -var BlockingMode = 2; -var ConcurrentMode = 4; -var ProfileMode = 8; -var DebugTracingMode = 16; +var BlockingMode = + /* */ + 1; +var ConcurrentMode = + /* */ + 2; +var ProfileMode = + /* */ + 4; +var DebugTracingMode = + /* */ + 8; +var StrictLegacyMode = + /* */ + 16; var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = 0; @@ -5891,7 +5978,7 @@ var ReactStrictModeWarnings = { var node = fiber; while (node !== null) { - if (node.mode & StrictMode) { + if (node.mode & StrictLegacyMode) { maybeStrictRoot = node; } @@ -5922,7 +6009,7 @@ var ReactStrictModeWarnings = { fiber, instance ) { - // Dedup strategy: Warn once per component. + // Dedupe strategy: Warn once per component. if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } @@ -5935,7 +6022,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function" ) { pendingUNSAFE_ComponentWillMountWarnings.push(fiber); @@ -5949,7 +6036,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); @@ -5963,7 +6050,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function" ) { pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); @@ -6281,9 +6368,7 @@ function exitDisallowedContextReadInDEV() { isDisallowedContextReadInDEV = false; } } -function pushProvider(providerFiber, nextValue) { - var context = providerFiber.type._context; - +function pushProvider(providerFiber, context, nextValue) { { push(valueCursor, context._currentValue2, providerFiber); context._currentValue2 = nextValue; @@ -6304,10 +6389,9 @@ function pushProvider(providerFiber, nextValue) { } } } -function popProvider(providerFiber) { +function popProvider(context, providerFiber) { var currentValue = valueCursor.current; pop(valueCursor, providerFiber); - var context = providerFiber.type._context; { context._currentValue2 = currentValue; @@ -6394,20 +6478,35 @@ function propagateContextChange( // Match! Schedule an update on this fiber. if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate( - NoTimestamp, - pickArbitraryLane(renderLanes) - ); + var lane = pickArbitraryLane(renderLanes); + var update = createUpdate(NoTimestamp, lane); update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the // update to the current fiber, too, which means it will persist even if // this render is thrown away. Since it's a race condition, not sure it's // worth fixing. + // Inlined `enqueueUpdate` to remove interleaved update check - enqueueUpdate(fiber, update); - } + var updateQueue = fiber.updateQueue; - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; + if (updateQueue === null); + else { + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + sharedQueue.pending = update; + } + } + + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; if (alternate !== null) { alternate.lanes = mergeLanes(alternate.lanes, renderLanes); @@ -6538,6 +6637,48 @@ function readContext(context, observedBits) { return context._currentValue2; } +// An array of all update queues that received updates during the current +// render. When this render exits, either because it finishes or because it is +// interrupted, the interleaved updates will be transfered onto the main part +// of the queue. +var interleavedQueues = null; +function pushInterleavedQueue(queue) { + if (interleavedQueues === null) { + interleavedQueues = [queue]; + } else { + interleavedQueues.push(queue); + } +} +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 + // point to the last node in a circular linked list. We need to append the + // interleaved list to the end of the pending list by joining them into a + // single, circular list. + if (interleavedQueues !== null) { + for (var i = 0; i < interleavedQueues.length; i++) { + var queue = interleavedQueues[i]; + var lastInterleavedUpdate = queue.interleaved; + + if (lastInterleavedUpdate !== null) { + queue.interleaved = null; + var firstInterleavedUpdate = lastInterleavedUpdate.next; + var lastPendingUpdate = queue.pending; + + if (lastPendingUpdate !== null) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = firstInterleavedUpdate; + lastInterleavedUpdate.next = firstPendingUpdate; + } + + queue.pending = lastInterleavedUpdate; + } + } + + interleavedQueues = null; + } +} + var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -6560,7 +6701,9 @@ function initializeUpdateQueue(fiber) { firstBaseUpdate: null, lastBaseUpdate: null, shared: { - pending: null + pending: null, + interleaved: null, + lanes: NoLanes }, effects: null }; @@ -6593,7 +6736,7 @@ function createUpdate(eventTime, lane) { }; return update; } -function enqueueUpdate(fiber, update) { +function enqueueUpdate(fiber, update, lane) { var updateQueue = fiber.updateQueue; if (updateQueue === null) { @@ -6602,17 +6745,35 @@ function enqueueUpdate(fiber, update) { } var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (isInterleavedUpdate(fiber)) { + var interleaved = sharedQueue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(sharedQueue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + sharedQueue.interleaved = update; } else { - update.next = pending.next; - pending.next = update; - } + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - sharedQueue.pending = update; + sharedQueue.pending = update; + } { if ( @@ -6630,6 +6791,33 @@ function enqueueUpdate(fiber, update) { } } } +function entangleTransitions(root, fiber, lane) { + var updateQueue = fiber.updateQueue; + + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; + } + + var sharedQueue = updateQueue.shared; + + if (isTransitionLane(lane)) { + var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must + // have finished. We can remove them from the shared queue, which represents + // a superset of the actually pending lanes. In some cases we may entangle + // more than we need to, but that's OK. In fact it's worse if we *don't* + // entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } +} function enqueueCapturedUpdate(workInProgress, capturedUpdate) { // Captured updates are updates that are thrown by a child during the render // phase. They should be discarded if the render is aborted. Therefore, @@ -6731,7 +6919,7 @@ function getStateFromUpdate( var nextState = payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -6769,7 +6957,7 @@ function getStateFromUpdate( partialState = _payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -6959,7 +7147,24 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { queue.baseState = newBaseState; queue.firstBaseUpdate = newFirstBaseUpdate; - queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. + queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.shared.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + newLanes = mergeLanes(newLanes, interleaved.lane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (firstBaseUpdate === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.shared.lanes = NoLanes; + } // Set the remaining expiration time to be whatever is remaining in the queue. // This should be fine because the only two other things that contribute to // expiration time are props and context. We're already in the middle of the // begin phase by the time we start processing the queue, so we've already @@ -7100,7 +7305,7 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7149,7 +7354,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); @@ -7168,7 +7377,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); @@ -7186,7 +7399,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } } }; @@ -7203,7 +7420,7 @@ function checkShouldComponentUpdate( if (typeof instance.shouldComponentUpdate === "function") { { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7539,7 +7756,7 @@ function constructClassInstance(workInProgress, ctor, props) { } // Instantiate twice to help detect side-effects. { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7752,7 +7969,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -7796,7 +8013,9 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } } @@ -7858,7 +8077,9 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } return false; @@ -7904,13 +8125,17 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8160,7 +8385,7 @@ function coerceRef(returnFiber, current, element) { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant if ( - (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + (returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs // because these cannot be automatically converted to an arrow function // using a codemod. Therefore, we don't have to warn about string refs again. !( @@ -8262,12 +8487,14 @@ function coerceRef(returnFiber, current, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { + var childString = Object.prototype.toString.call(newChild); + { throw Error( "Objects are not valid as a React child (found: " + - (Object.prototype.toString.call(newChild) === "[object Object]" + (childString === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : childString) + "). If you meant to render a collection of children, use an array instead." ); } @@ -8290,7 +8517,7 @@ function warnOnFunctionType(returnFiber) { "Or maybe you meant to call this function rather than return it." ); } -} // 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. @@ -8300,23 +8527,16 @@ function ChildReconciler(shouldTrackSideEffects) { if (!shouldTrackSideEffects) { // Noop. return; - } // Deletions are added in reversed order so we add it to the front. - // At this point, the return fiber's effect list is empty except for - // deletions, so we can just append the deletion to the list. The remaining - // effects aren't added until the complete phase. Once we implement - // resuming, this may not be true. + } - var last = returnFiber.lastEffect; + var deletions = returnFiber.deletions; - if (last !== null) { - last.nextEffect = childToDelete; - returnFiber.lastEffect = childToDelete; + if (deletions === null) { + returnFiber.deletions = [childToDelete]; + returnFiber.flags |= ChildDeletion; } else { - returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + deletions.push(childToDelete); } - - childToDelete.nextEffect = null; - childToDelete.flags = Deletion; } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -8380,7 +8600,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (oldIndex < lastPlacedIndex) { // This is a move. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } else { // This item can stay in place. @@ -8388,7 +8608,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } else { // This is an insertion. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } } @@ -8397,7 +8617,7 @@ function ChildReconciler(shouldTrackSideEffects) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { - newFiber.flags = Placement; + newFiber.flags |= Placement; } return newFiber; @@ -8418,10 +8638,26 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current, element, lanes) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + } + if (current !== null) { if ( - current.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current, element) + current.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. + // 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 ) { // Move based on index var existing = useFiber(current, element.props); @@ -8560,16 +8796,6 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ); - } - return updateElement(returnFiber, oldFiber, newChild, lanes); } else { return null; @@ -8627,16 +8853,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key === null ? newIdx : newChild.key ) || null; - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - _matchedFiber, - newChild.props.children, - lanes, - newChild.key - ); - } - return updateElement(returnFiber, _matchedFiber, newChild, lanes); } @@ -9130,45 +9346,43 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - switch (child.tag) { - case Fragment: { - if (element.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, element.props.children); - existing.return = returnFiber; + var elementType = element.type; - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; - return existing; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - break; + return existing; } + } else { + if ( + child.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. + // 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 + ) { + deleteRemainingChildren(returnFiber, child.sibling); - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing = useFiber(child, element.props); - - _existing.ref = coerceRef(returnFiber, child, element); - _existing.return = returnFiber; + var _existing = useFiber(child, element.props); - { - _existing._debugSource = element._source; - _existing._debugOwner = element._owner; - } + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; - return _existing; + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; } - break; + return _existing; } } // Didn't match. @@ -9599,21 +9813,6 @@ function findFirstSuspended(row) { return null; } -var NoFlags$1 = - /* */ - 0; // Represents whether effect should fire. - -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ - 2; -var Passive$1 = - /* */ - 4; - var isHydrating = false; function enterHydrationState(fiber) { @@ -9709,6 +9908,12 @@ function warnAboutMultipleRenderersDEV(mutableSource) { } } // Eager reads the version of a mutable source and stores it on the root. +function getSuspendedCachePool() { + { + return null; + } // We check the cache on the stack first, since that's the one any new Caches +} + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; @@ -9994,7 +10199,20 @@ function renderWithHooks( { currentHookNameInDev = null; hookTypesDev = null; - hookTypesUpdateIndexDev = -1; + hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last + // render. If this fires, it suggests that we incorrectly reset the static + // flags in some other part of the codebase. This has happened before, for + // example, in the SuspenseList implementation. + + if ( + current !== null && + (current.flags & PassiveStatic) !== (workInProgress.flags & PassiveStatic) + ) { + error( + "Internal React error: Expected static flag was missing. Please " + + "notify the React team." + ); + } } didScheduleRenderPhaseUpdate = false; @@ -10008,8 +10226,13 @@ function renderWithHooks( return children; } function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; - workInProgress.flags &= ~(Passive | Update); + workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the + // complete phase (bubbleProperties). + + { + workInProgress.flags &= ~(Passive | Update); + } + current.lanes = removeLanes(current.lanes, lanes); } function resetHooksAfterThrow() { @@ -10160,6 +10383,8 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState @@ -10297,6 +10522,28 @@ function updateReducer(reducer, initialArg, init) { hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; + } // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + var interleavedLane = interleaved.lane; + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + interleavedLane + ); + markSkippedUpdateLanes(interleavedLane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (baseQueue === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.lanes = NoLanes; } var dispatch = queue.dispatch; @@ -10424,11 +10671,48 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { // // This can lead to tearing in the first renderer when it resumes, // but there's nothing we can do about that (short of throwing here and refusing to continue the render). - markSourceAsDirty(source); + markSourceAsDirty(source); // Intentioally throw an error to force React to retry synchronously. During + // the synchronous retry, it will block interleaved mutations, so we should + // get a consistent read. Therefore, the following error should never be + // visible to the user. + // + // If it were to become visible to the user, it suggests one of two things: + // a bug in React, or (more likely), a mutation during the render phase that + // caused the second re-render attempt to be different from the first. + // + // We know it's the second case if the logs are currently disabled. So in + // dev, we can present a more accurate error message. + + { + // eslint-disable-next-line react-internal/no-production-logging + if (console.log.__reactDisabledLog) { + // If the logs are disabled, this is the dev-only double render. This is + // only reachable if there was a mutation during render. Show a helpful + // error message. + // + // Something interesting to note: because we only double render in + // development, this error will never happen during production. This is + // actually true of all errors that occur during a double render, + // because if the first render had thrown, we would have exited the + // begin phase without double rendering. We should consider suppressing + // any error from a double render (with a warning) to more closely match + // the production behavior. + var componentName = getComponentName(currentlyRenderingFiber$1.type); + + { + throw Error( + "A mutable source was mutated while the " + + componentName + + " component was rendering. This is not supported. Move any mutations into event handlers or effects." + ); + } + } + } // We expect this error not to be thrown during the synchronous retry, + // because we blocked interleaved mutations. { throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } } @@ -10564,6 +10848,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { // including any interleaving updates that occur. var newQueue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -10611,6 +10897,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -10704,7 +10992,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); return; } } @@ -10720,15 +11008,19 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { } function mountEffect(create, deps) { - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + { + return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); + } } function updateEffect(create, deps) { - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + return updateEffectImpl(Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + { + return mountEffectImpl(Update, Layout, create, deps); + } } function updateLayoutEffect(create, deps) { @@ -10780,12 +11072,15 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; - return mountEffectImpl( - Update, - Layout, - imperativeHandleEffect.bind(null, create, ref), - effectDeps - ); + + { + return mountEffectImpl( + Update, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); + } } function updateImperativeHandle(ref, create, deps) { @@ -10940,15 +11235,15 @@ function startTransition(setPending, callback) { { runWithPriority( - priorityLevel < UserBlockingPriority$1 - ? UserBlockingPriority$1 + priorityLevel < UserBlockingPriority + ? UserBlockingPriority : priorityLevel, function() { setPending(true); } ); runWithPriority( - priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, + priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function() { var prevTransition = ReactCurrentBatchConfig$1.transition; ReactCurrentBatchConfig$1.transition = 1; @@ -11060,19 +11355,7 @@ function dispatchAction(fiber, queue, action) { eagerReducer: null, eagerState: null, next: null - }; // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - queue.pending = update; + }; var alternate = fiber.alternate; if ( @@ -11083,7 +11366,47 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; } else { + if (isInterleavedUpdate(fiber)) { + var interleaved = queue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + queue.interleaved = update; + } else { + var _pending = queue.pending; + + if (_pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = _pending.next; + _pending.next = update; + } + + queue.pending = update; + } + if ( fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes) @@ -11128,7 +11451,24 @@ function dispatchAction(fiber, queue, action) { } } - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (isTransitionLane(lane) && root !== null) { + var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they + // must have finished. We can remove them from the shared queue, which + // represents a superset of the actually pending lanes. In some cases we + // may entangle more than we need to, but that's OK. In fact it's worse if + // we *don't* entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } } } @@ -11150,6 +11490,7 @@ var ContextOnlyDispatcher = { useOpaqueIdentifier: throwInvalidHookError, unstable_isNewReconciler: enableNewReconciler }; + var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; @@ -11279,6 +11620,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnMountWithHookTypesInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11376,6 +11718,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11473,6 +11816,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11570,6 +11914,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -11682,6 +12027,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -11794,6 +12140,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -11836,218 +12183,621 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; var prevDispatcher = ReactCurrentDispatcher$1.current; ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(source, getSnapshot, subscribe); + }, + useOpaqueIdentifier: function() { + currentHookNameInDev = "useOpaqueIdentifier"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderOpaqueIdentifier(); + }, + unstable_isNewReconciler: enableNewReconciler + }; +} + +var now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; + +function getCommitTime() { + return commitTime; +} + +function recordCommitTime() { + commitTime = now$1(); +} + +function startProfilerTimer(fiber) { + profilerStartTime = now$1(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); + } +} + +function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} + +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } +} + +function transferActualDuration(fiber) { + // Transfer time spent rendering these children so we don't lose it + // after we rerender. This is used as a helper in special cases + // where we should count the work of multiple passes. + var child = fiber.child; + + while (child) { + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } +} + +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; + +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} + +function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + if (current === null) { + // If this is a fresh new component that hasn't been rendered yet, we + // won't update its child set by applying minimal side-effects. Instead, + // we will add them all to the child before it gets rendered. That means + // we can optimize this reconciliation pass by not tracking side-effects. + workInProgress.child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + // If the current child is the same as the work in progress, it means that + // we haven't yet started any work on these children. Therefore, we use + // the clone algorithm to create a copy of all the current children. + // If we had any progressed work already, that is invalid at this point so + // let's throw it out. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + nextChildren, + renderLanes + ); + } +} + +function forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes +) { + // This function is fork of reconcileChildren. It's used in cases where we + // want to reconcile without matching against the existing set. This has the + // effect of all current children being unmounted; even if the type and key + // are the same, the old child is unmounted and a new child is created. + // + // To do this, we're going to go through the reconcile algorithm twice. In + // the first pass, we schedule a deletion for all the current children by + // passing null. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + null, + renderLanes + ); // In the second pass, we mount the new children. The trick here is that we + // pass null in place of where we usually pass the current child set. This has + // the effect of remounting all children regardless of whether their + // identities match. + + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); +} + +function updateForwardRef( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; + + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) + ); + } + } + } + + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + } finally { + reenableLogs(); + } + } + + setIsRendering(false); + } + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateLanes, + renderLanes +) { + if (current === null) { + var type = Component.type; + + if ( + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined + ) { + var resolvedType = type; + + { + resolvedType = resolveFunctionForHotReloading(type); + } // If this is a plain function component without default props, + // and with only the default shallow comparison, we upgrade it + // to a SimpleMemoComponent to allow fast path updates. + + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + updateLanes, + renderLanes + ); + } + + { + var innerPropTypes = type.propTypes; + + if (innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(type) + ); + } + } + + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } + + { + var _type = Component.type; + var _innerPropTypes = _type.propTypes; + + if (_innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + _innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(_type) + ); + } + } + + var currentChild = current.child; // This is always exactly one child + + if (!includesSomeLane(updateLanes, renderLanes)) { + // This will be the props with resolved defaultProps, + // unlike current.memoizedProps which will be the unresolved ones. + var prevProps = currentChild.memoizedProps; // Default to shallow comparison + + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; + + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; +} + +function updateSimpleMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateLanes, + renderLanes +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens when the inner render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var outerMemoType = workInProgress.elementType; + + if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { + // We warn when you define propTypes on lazy() + // so let's just skip over it to find memo() outer wrapper. + // Inner props for memo are validated later. + var lazyComponent = outerMemoType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + + try { + outerMemoType = init(payload); + } catch (x) { + outerMemoType = null; + } // Inner propTypes will be validated in the function component path. + + var outerPropTypes = outerMemoType && outerMemoType.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentName(outerMemoType) + ); + } } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + } + } - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + if (current !== null) { + var prevProps = current.memoizedProps; - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type + ) { + didReceiveUpdate = false; + + if (!includesSomeLane(renderLanes, updateLanes)) { + // The pending lanes were cleared at the beginning of beginWork. We're + // about to bail out, but there might be other lanes that weren't + // included in the current render. Usually, the priority level of the + // remaining updates is accumlated during the evaluation of the + // component (i.e. when processing the update queue). But since since + // we're bailing out early *without* evaluating the component, we need + // to account for it here, too. Reset to the value of the current fiber. + // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, + // because a MemoComponent fiber does not have hooks or an update queue; + // rather, it wraps around an inner component, which may or may not + // contains hooks. + // TODO: Move the reset at in beginWork out of the common path so that + // this is no longer necessary. + workInProgress.lanes = current.lanes; + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useDeferredValue: function(value) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value); - }, - useTransition: function() { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(); - }, - useMutableSource: function(source, getSnapshot, subscribe) { - currentHookNameInDev = "useMutableSource"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateMutableSource(source, getSnapshot, subscribe); - }, - useOpaqueIdentifier: function() { - currentHookNameInDev = "useOpaqueIdentifier"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderOpaqueIdentifier(); - }, - unstable_isNewReconciler: enableNewReconciler - }; + } + } + + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); } -var now$1 = Scheduler.unstable_now; -var commitTime = 0; -var profilerStartTime = -1; +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var prevState = current !== null ? current.memoizedState : null; // If this is not null, this is a cache pool that was carried over from the + // previous render. We will push this to the cache pool context so that we can + // resume in-flight requests. -function getCommitTime() { - return commitTime; -} + var spawnedCachePool = null; -function recordCommitTime() { - commitTime = now$1(); -} + if ( + nextProps.mode === "hidden" || + nextProps.mode === "unstable-defer-without-hiding" + ) { + // Rendering a hidden tree. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Figure out what we should do in Blocking mode. + var nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = nextState; + pushRenderLanes(workInProgress, renderLanes); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. + var nextBaseLanes; -function startProfilerTimer(fiber) { - profilerStartTime = now$1(); + if (prevState !== null) { + var prevBaseLanes = prevState.baseLanes; + nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); + } else { + nextBaseLanes = renderLanes; + } // Schedule this fiber to re-render at offscreen priority. Then bailout. - if (fiber.actualStartTime < 0) { - fiber.actualStartTime = now$1(); - } -} + { + markSpawnedWork(OffscreenLane); + } -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; -} + workInProgress.lanes = workInProgress.childLanes = laneToLanes( + OffscreenLane + ); + var _nextState = { + baseLanes: nextBaseLanes, + cachePool: spawnedCachePool + }; + workInProgress.memoizedState = _nextState; + workInProgress.updateQueue = null; // We're about to bail out, but we need to push this to the stack anyway + // to avoid a push/pop misalignment. -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; + pushRenderLanes(workInProgress, nextBaseLanes); + return null; + } else { + var _nextState2 = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. - if (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; + var subtreeRenderLanes = + prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); } + } else { + // Rendering a visible tree. + var _subtreeRenderLanes; - profilerStartTime = -1; - } -} + if (prevState !== null) { + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); -function transferActualDuration(fiber) { - // Transfer time spent rendering these children so we don't lose it - // after we rerender. This is used as a helper in special cases - // where we should count the work of multiple passes. - var child = fiber.child; + workInProgress.memoizedState = null; + } else { + // We weren't previously hidden, and we still aren't, so there's nothing + // special to do. Need to push to the stack regardless, though, to avoid + // a push/pop misalignment. + _subtreeRenderLanes = renderLanes; + } - while (child) { - fiber.actualDuration += child.actualDuration; - child = child.sibling; + pushRenderLanes(workInProgress, _subtreeRenderLanes); } -} -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; -var didReceiveUpdate = false; -var didWarnAboutBadClass; -var didWarnAboutModulePatternComponent; -var didWarnAboutContextTypeOnFunctionComponent; -var didWarnAboutGetDerivedStateOnFunctionComponent; -var didWarnAboutFunctionRefs; -var didWarnAboutReassigningProps; -var didWarnAboutRevealOrder; -var didWarnAboutTailOptions; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} // Note: These happen to have identical begin phases, for now. We shouldn't hold +// ourselves to this constraint, though. If the behavior diverges, we should +// fork the function. -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; -} +var updateLegacyHiddenComponent = updateOffscreenComponent; -function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { - if (current === null) { - // If this is a fresh new component that hasn't been rendered yet, we - // won't update its child set by applying minimal side-effects. Instead, - // we will add them all to the child before it gets rendered. That means - // we can optimize this reconciliation pass by not tracking side-effects. - workInProgress.child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - } else { - // If the current child is the same as the work in progress, it means that - // we haven't yet started any work on these children. Therefore, we use - // the clone algorithm to create a copy of all the current children. - // If we had any progressed work already, that is invalid at this point so - // let's throw it out. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); +function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + +function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + +function updateProfiler(current, workInProgress, renderLanes) { + { + workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; } + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes -) { - // This function is fork of reconcileChildren. It's used in cases where we - // want to reconcile without matching against the existing set. This has the - // effect of all current children being unmounted; even if the type and key - // are the same, the old child is unmounted and a new child is created. - // - // To do this, we're going to go through the reconcile algorithm twice. In - // the first pass, we schedule a deletion for all the current children by - // passing null. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ); // In the second pass, we mount the new children. The trick here is that we - // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their - // identities match. +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; + } } -function updateForwardRef( +function updateFunctionComponent( current, workInProgress, Component, nextProps, renderLanes ) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens after the first render suspends. - // We'll need to figure out if this is fine or can cause issues. { if (workInProgress.type !== workInProgress.elementType) { // Lazy component props can't be validated in createElement @@ -12065,8 +12815,12 @@ function updateForwardRef( } } - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + var context; + + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } var nextChildren; prepareToReadContext(workInProgress, renderLanes); @@ -12077,22 +12831,22 @@ function updateForwardRef( nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); } finally { @@ -12113,3049 +12867,3319 @@ function updateForwardRef( return workInProgress.child; } -function updateMemoComponent( +function updateClassComponent( current, workInProgress, Component, nextProps, - updateLanes, renderLanes ) { - if (current === null) { - var type = Component.type; - - if ( - isSimpleFunctionComponent(type) && - Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. - Component.defaultProps === undefined - ) { - var resolvedType = type; - - { - resolvedType = resolveFunctionForHotReloading(type); - } // If this is a plain function component without default props, - // and with only the default shallow comparison, we upgrade it - // to a SimpleMemoComponent to allow fast path updates. - - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; - - { - validateFunctionComponentInDev(workInProgress, type); - } - - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - renderLanes - ); - } - - { - var innerPropTypes = type.propTypes; + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; if (innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. checkPropTypes( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(type) + getComponentName(Component) ); } } + } // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; - } - - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + var hasContext; - if (_innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. - checkPropTypes( - _innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(_type) - ); - } + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - var currentChild = current.child; // This is always exactly one child - - if (!includesSomeLane(updateLanes, renderLanes)) { - // This will be the props with resolved defaultProps, - // unlike current.memoizedProps which will be the unresolved ones. - var prevProps = currentChild.memoizedProps; // Default to shallow comparison - - var compare = Component.compare; - compare = compare !== null ? compare : shallowEqual; - - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } - } // React DevTools reads this flag. + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; - workInProgress.flags |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); - newChild.ref = workInProgress.ref; - newChild.return = workInProgress; - workInProgress.child = newChild; - return newChild; -} + 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 -function updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateLanes, - renderLanes -) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens when the inner render suspends. - // We'll need to figure out if this is fine or can cause issues. - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var outerMemoType = workInProgress.elementType; + workInProgress.flags |= Placement; + } // In the initial pass we might need to construct the instance. - if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { - // We warn when you define propTypes on lazy() - // so let's just skip over it to find memo() outer wrapper. - // Inner props for memo are validated later. - var lazyComponent = outerMemoType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + shouldUpdate = true; + } else if (current === null) { + // In a resume, we'll already have an instance we can reuse. + shouldUpdate = resumeMountClassInstance( + workInProgress, + Component, + nextProps, + renderLanes + ); + } else { + shouldUpdate = updateClassInstance( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); + } - try { - outerMemoType = init(payload); - } catch (x) { - outerMemoType = null; - } // Inner propTypes will be validated in the function component path. + var nextUnitOfWork = finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ); - var outerPropTypes = outerMemoType && outerMemoType.propTypes; + { + var inst = workInProgress.stateNode; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentName(outerMemoType) - ); - } + if (shouldUpdate && inst.props !== nextProps) { + if (!didWarnAboutReassigningProps) { + error( + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentName(workInProgress.type) || "a component" + ); } + + didWarnAboutReassigningProps = true; } } - if (current !== null) { - var prevProps = current.memoizedProps; + return nextUnitOfWork; +} - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type - ) { - didReceiveUpdate = false; +function finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes +) { + // Refs should update even if shouldComponentUpdate returns false + markRef(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; - if (!includesSomeLane(renderLanes, updateLanes)) { - // The pending lanes were cleared at the beginning of beginWork. We're - // about to bail out, but there might be other lanes that weren't - // included in the current render. Usually, the priority level of the - // remaining updates is accumlated during the evaluation of the - // component (i.e. when processing the update queue). But since since - // we're bailing out early *without* evaluating the component, we need - // to account for it here, too. Reset to the value of the current fiber. - // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, - // because a MemoComponent fiber does not have hooks or an update queue; - // rather, it wraps around an inner component, which may or may not - // contains hooks. - // TODO: Move the reset at in beginWork out of the common path so that - // this is no longer necessary. - workInProgress.lanes = current.lanes; - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } + if (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); } + + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); -} + var instance = workInProgress.stateNode; // Rerender -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - var prevState = current !== null ? current.memoizedState : null; + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; if ( - nextProps.mode === "hidden" || - nextProps.mode === "unstable-defer-without-hiding" + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" ) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy sync mode, don't defer the subtree. Render it now. - // TODO: Figure out what we should do in Blocking mode. - var nextState = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = nextState; - pushRenderLanes(workInProgress, renderLanes); - } else if (!includesSomeLane(renderLanes, OffscreenLane)) { - var nextBaseLanes; + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; - if (prevState !== null) { - var prevBaseLanes = prevState.baseLanes; - nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); - } else { - nextBaseLanes = renderLanes; - } // Schedule this fiber to re-render at offscreen priority. Then bailout. + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); - { - markSpawnedWork(OffscreenLane); + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + instance.render(); + } finally { + reenableLogs(); + } } - workInProgress.lanes = workInProgress.childLanes = laneToLanes( - OffscreenLane - ); - var _nextState = { - baseLanes: nextBaseLanes - }; - workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway - // to avoid a push/pop misalignment. + setIsRendering(false); + } + } // React DevTools reads this flag. - pushRenderLanes(workInProgress, nextBaseLanes); - return null; - } else { - // Rendering at offscreen, so we can clear the base lanes. - var _nextState2 = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. + workInProgress.flags |= PerformedWork; - var subtreeRenderLanes = - prevState !== null ? prevState.baseLanes : renderLanes; - pushRenderLanes(workInProgress, subtreeRenderLanes); - } + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes + ); } else { - var _subtreeRenderLanes; - - if (prevState !== null) { - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. - workInProgress.memoizedState = null; - } else { - // We weren't previously hidden, and we still aren't, so there's nothing - // special to do. Need to push to the stack regardless, though, to avoid - // a push/pop misalignment. - _subtreeRenderLanes = renderLanes; - } + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. - pushRenderLanes(workInProgress, _subtreeRenderLanes); + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); } - reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; -} // Note: These happen to have identical begin phases, for now. We shouldn't hold -// ourselves to this constraint, though. If the behavior diverges, we should -// fork the function. +} -var updateLegacyHiddenComponent = updateOffscreenComponent; +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; -function updateFragment(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + if (root.pendingContext) { + pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); + } -function updateMode(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + pushHostContainer(workInProgress, root.containerInfo); } -function updateProfiler(current, workInProgress, renderLanes) { - { - workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + if (!(current !== null && updateQueue !== null)) { + throw Error( + "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." + ); + } + + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState.element; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; + var root = workInProgress.stateNode; + // being called "element". + + var nextChildren = nextState.element; + + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + + if (root.hydrate && enterHydrationState()) { + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + workInProgress.child = child; + var node = child; + + while (node) { + // Mark each child 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. + node.flags = (node.flags & ~Placement) | Hydrating; + node = node.sibling; + } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren(current, workInProgress, nextChildren, renderLanes); } + return workInProgress.child; +} + +function updateHostComponent(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); + + var type = workInProgress.type; var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; var nextChildren = nextProps.children; + + if (prevProps !== null && shouldSetTextContent()) { + // If we're switching from a direct text child to a normal child, or to + // empty, we need to schedule the text content to be reset. + workInProgress.flags |= ContentReset; + } + + markRef(current, workInProgress); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef(current, workInProgress) { - var ref = workInProgress.ref; +function updateHostText(current, workInProgress) { + // immediately after. - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } + return null; } -function updateFunctionComponent( - current, +function mountLazyComponent( + _current, workInProgress, - Component, - nextProps, + elementType, + updateLanes, renderLanes ) { - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + 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 - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } + workInProgress.flags |= Placement; } - var context; + var props = workInProgress.pendingProps; + var lazyComponent = elementType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + var Component = init(payload); // Store the unwrapped component in the type. - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component + ); + } - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes - ); + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - if (workInProgress.mode & StrictMode) { - disableLogs(); + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component + ); + } - try { - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); - } finally { - reenableLogs(); } + + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; } - setIsRendering(false); + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component) + ); + } + } + } + + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateLanes, + renderLanes + ); + return child; + } } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. + var hint = ""; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } } -function updateClassComponent( - current, +function mountIncompleteClassComponent( + _current, workInProgress, Component, nextProps, renderLanes ) { - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + 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. + + workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` + // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } + + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); +} + +function mountIndeterminateComponent( + _current, + workInProgress, + 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 - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } - } // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. + workInProgress.flags |= Placement; + } - var hasContext; + var props = workInProgress.pendingProps; + var context; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); } prepareToReadContext(workInProgress, renderLanes); - var instance = workInProgress.stateNode; - var shouldUpdate; + var value; - 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 + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName + ); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - shouldUpdate = true; - } else if (current === null) { - // In a resume, we'll already have an instance we can reuse. - shouldUpdate = resumeMountClassInstance( - workInProgress, - Component, - nextProps, - renderLanes - ); - } else { - shouldUpdate = updateClassInstance( - current, + didWarnAboutBadClass[componentName] = true; + } + } + + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } + + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, workInProgress, Component, - nextProps, + props, + context, renderLanes ); - } + setIsRendering(false); + } // React DevTools reads this flag. - var nextUnitOfWork = finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes - ); + workInProgress.flags |= PerformedWork; { - var inst = workInProgress.stateNode; + // Support for module components is deprecated and is removed behind a flag. + // Whether or not it would crash later, we want to show a good message in DEV first. + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + var _componentName = getComponentName(Component) || "Unknown"; - if (shouldUpdate && inst.props !== nextProps) { - if (!didWarnAboutReassigningProps) { + if (!didWarnAboutModulePatternComponent[_componentName]) { error( - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName, + _componentName, + _componentName ); - } - didWarnAboutReassigningProps = true; + didWarnAboutModulePatternComponent[_componentName] = true; + } } } - return nextUnitOfWork; -} + if ( + // Run these checks in production only if the flag is off. + // Eventually we'll delete this branch altogether. + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + { + var _componentName2 = getComponentName(Component) || "Unknown"; -function finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes -) { - // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); - var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; + if (!didWarnAboutModulePatternComponent[_componentName2]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName2, + _componentName2, + _componentName2 + ); - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - var instance = workInProgress.stateNode; // Rerender + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + var hasContext = false; - if ( - didCaptureError && - typeof Component.getDerivedStateFromError !== "function" - ) { - // If we captured an error, but getDerivedStateFromError is not defined, - // unmount all the children. componentDidCatch will schedule an update to - // re-render a fallback. This is temporary until we migrate everyone to - // the new API. - // TODO: Warn in a future release. - nextChildren = null; + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - { - stopProfilerTimerIfRunning(); + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + var getDerivedStateFromProps = Component.getDerivedStateFromProps; + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); } + + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); } else { - { - setIsRendering(true); - nextChildren = instance.render(); + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; - if (workInProgress.mode & StrictMode) { + { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { - instance.render(); + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); } finally { reenableLogs(); } } - - setIsRendering(false); } - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; - if (current !== null && didCaptureError) { - // If we're recovering from an error, reconcile without reusing any of - // the existing children. Conceptually, the normal children and the children - // that are shown on error are two different sets, so we shouldn't reuse - // normal children even if their identities match. - forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes - ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } // Memoize state using the values we just used to render. - // TODO: Restructure so we never read values from the instance. + reconcileChildren(null, workInProgress, value, renderLanes); - workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + { + validateFunctionComponentInDev(workInProgress, Component); + } - if (hasContext) { - invalidateContextProvider(workInProgress, Component, true); + return workInProgress.child; } - - return workInProgress.child; } -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; - - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, false); - } +function validateFunctionComponentInDev(workInProgress, Component) { + { + if (Component) { + if (Component.childContextTypes) { + error( + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ); + } + } - pushHostContainer(workInProgress, root.containerInfo); -} + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); -function updateHostRoot(current, workInProgress, renderLanes) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - if (!(current !== null && updateQueue !== null)) { - throw Error( - "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." - ); - } + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - var nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property - // being called "element". + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - var nextChildren = nextState.element; + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } + } - var root = workInProgress.stateNode; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentName(Component) || "Unknown"; - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 + ); - while (node) { - // Mark each child 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. - node.flags = (node.flags & ~Placement) | Hydrating; - node = node.sibling; + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } } - } else { - // Otherwise reset hydration state in case we aborted and resumed another - // root. - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } - - return workInProgress.child; -} -function updateHostComponent(current, workInProgress, renderLanes) { - pushHostContext(workInProgress); + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentName(Component) || "Unknown"; - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error( + "%s: Function components do not support contextType.", + _componentName4 + ); - if (prevProps !== null && shouldSetTextContent()) { - // If we're switching from a direct text child to a normal child, or to - // empty, we need to schedule the text content to be reset. - workInProgress.flags |= ContentReset; + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } + } } - - markRef(current, workInProgress); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; } -function updateHostText(current, workInProgress) { - // immediately after. +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; - return null; +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCachePool() + }; } -function mountLazyComponent( - _current, +function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; + + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool + }; +} // TODO: Probably should inline this back + +function shouldRemainOnFallback( + suspenseContext, + current, workInProgress, - elementType, - updateLanes, 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 + // If we're already showing a fallback, there are cases where we need to + // remain on that fallback regardless of whether the content has resolved. + // For example, SuspenseList coordinates when nested content appears. + if (current !== null) { + var suspenseState = current.memoizedState; - workInProgress.flags |= Placement; + if (suspenseState === null) { + // Currently showing content. Don't hide it, even if ForceSuspenseFallack + // is true. More precise name might be "ForceRemainSuspenseFallback". + // Note: This is a factoring smell. Can't remain on a fallback if there's + // no fallback to remain on. + return false; + } + } // Not currently showing content. Consult the Suspense context. + + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); +} + +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); +} + +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + + { + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; + } } - var props = workInProgress.pendingProps; - var lazyComponent = elementType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; - var Component = init(payload); // Store the unwrapped component in the type. + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; + if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + showFallback = true; + workInProgress.flags &= ~DidCapture; + } else { + // Attempting the main content + if (current === null || current.memoizedState !== null) { + // This is a new mount or this boundary is already showing a fallback state. + // Mark this subtree context as having at least one invisible parent that could + // handle the fallback state. + // Boundaries without fallbacks or should be avoided are not considered since + // they cannot handle preferred fallback states. + if ( + nextProps.fallback !== undefined && + nextProps.unstable_avoidThisFallback !== true + ) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext + ); + } + } + } + + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense + // boundary's children. This involves some custom reconcilation logic. Two + // main reasons this is so complicated. + // + // First, Legacy Mode has different semantics for backwards compatibility. The + // primary tree will commit in an inconsistent state, so when we do the + // second pass to render the fallback, we do some exceedingly, uh, clever + // hacks to make that not totally break. Like transferring effects and + // deletions from hidden tree. In Concurrent Mode, it's much simpler, + // because we bailout on the primary tree completely and leave it in its old + // state, no effects. Same as what we do for Offscreen (except that + // Offscreen doesn't have the first render pass). + // + // Second is hydration. During hydration, the Suspense fiber has a slightly + // different layout, where the child points to a dehydrated fragment, which + // contains the DOM rendered by the server. + // + // Third, even if you set all that aside, Suspense is like error boundaries in + // that we first we try to render one tree, and if that fails, we render again + // and switch to a different tree. Like a try/catch block. So we have to track + // which branch we're currently rendering. Ideally we would model this using + // a stack. + + if (current === null) { + // Initial mount + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined); - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component - ); - } + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; - child = updateFunctionComponent( - null, + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } - - child = updateClassComponent( - null, + var primaryChildFragment = workInProgress.child; + primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackFragment; + } else if (typeof nextProps.unstable_expectedLoadTime === "number") { + // This is a CPU-bound tree. Skip this tree and show a placeholder to + // unblock the surrounding content. Then immediately retry after the + // initial commit. + var _fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - case ForwardRef: { + var _primaryChildFragment = workInProgress.child; + _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; // 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; + { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component - ); + markSpawnedWork(SomeRetryLane); } - child = updateForwardRef( - null, + return _fallbackFragment; + } else { + return mountSuspensePrimaryChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, renderLanes ); - return child; } + } else { + // This is an update. + // If the current fiber has a SuspenseState, that means it's already showing + // a fallback. + var prevState = current.memoizedState; - case MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentName(Component) - ); - } - } + var _fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren2, + _nextFallbackChildren2, + 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; } + } else { + // The current tree is not already showing a fallback. + if (showFallback) { + // Timed out. + var _nextFallbackChildren3 = nextProps.fallback; + var _nextPrimaryChildren4 = nextProps.children; - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, - renderLanes - ); - return child; + var _fallbackChildFragment2 = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren4, + _nextFallbackChildren3, + 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; + } } } +} - var hint = ""; +function mountSuspensePrimaryChildren( + workInProgress, + primaryChildren, + renderLanes +) { + var mode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + renderLanes, + null + ); + primaryChildFragment.return = workInProgress; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; +function mountSuspenseFallbackChildren( + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + var fallbackChildFragment; + + if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) { + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; + + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = 0; + primaryChildFragment.treeBaseDuration = 0; } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } else { + primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + NoLanes, + null + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null ); } + + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; } -function mountIncompleteClassComponent( - _current, +function createWorkInProgressOffscreenFiber(current, offscreenProps) { + // The props argument to `createWorkInProgress` is `any` typed, so we use this + // wrapper function to constrain it. + return createWorkInProgress(current, offscreenProps); +} + +function updateSuspensePrimaryChildren( + current, workInProgress, - Component, - nextProps, + primaryChildren, 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 + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren + } + ); - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + if ((workInProgress.mode & BlockingMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; + } - workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` - // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - var hasContext; + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); + } } - prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); + workInProgress.child = primaryChildFragment; + return primaryChildFragment; } -function mountIndeterminateComponent( - _current, +function updateSuspenseFallbackChildren( + current, workInProgress, - Component, + primaryChildren, + fallbackChildren, 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; - } - - var props = workInProgress.pendingProps; - var context; - - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); - context = getMaskedContext(workInProgress, unmaskedContext); - } + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; - prepareToReadContext(workInProgress, renderLanes); - var value; + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was + // already cloned. In legacy mode, the only case where this isn't true is + // when DevTools forces us to display a fallback; we skip the first render + // pass entirely and go straight to rendering the fallback. (In Concurrent + // Mode, SuspenseList can also trigger this scenario, but this is a legacy- + // only codepath.) + workInProgress.child !== currentPrimaryChildFragment + ) { + var progressedPrimaryFragment = workInProgress.child; + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; - { - if ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = + 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. - if (!didWarnAboutBadClass[componentName]) { - error( - "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + - "This is likely to cause errors. Change %s to extend React.Component instead.", - componentName, - componentName - ); + workInProgress.deletions = null; + } else { + primaryChildFragment = createWorkInProgressOffscreenFiber( + 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.) - didWarnAboutBadClass[componentName] = true; - } - } + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } + var fallbackChildFragment; - setIsRendering(true); - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes + if (currentFallbackChildFragment !== null) { + fallbackChildFragment = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren ); - setIsRendering(false); - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; - - { - // Support for module components is deprecated and is removed behind a flag. - // Whether or not it would crash later, we want to show a good message in DEV first. - if ( - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - var _componentName = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutModulePatternComponent[_componentName]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName, - _componentName, - _componentName - ); + } else { + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. - didWarnAboutModulePatternComponent[_componentName] = true; - } - } + fallbackChildFragment.flags |= Placement; } - if ( - // Run these checks in production only if the flag is off. - // Eventually we'll delete this branch altogether. - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - { - var _componentName2 = getComponentName(Component) || "Unknown"; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - if (!didWarnAboutModulePatternComponent[_componentName2]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName2, - _componentName2, - _componentName2 - ); +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; - didWarnAboutModulePatternComponent[_componentName2] = true; - } - } // Proceed under the assumption that this is a class instance + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + scheduleWorkOnParentPath(fiber.return, renderLanes); +} - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderLanes +) { + // Mark any Suspense boundaries with fallbacks as having work to do. + // If they were previously forced into fallbacks, they may now be able + // to unblock. + var node = firstChild; - var hasContext = false; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + if (state !== null) { + scheduleWorkOnFiber(node, renderLanes); + } + } else if (node.tag === SuspenseListComponent) { + // If the tail is hidden there might not be an Suspense boundaries + // to schedule work on. In this case we have to schedule it on the + // list itself. + // We don't have to traverse to the children of the list since + // the list will propagate the change when it rerenders. + scheduleWorkOnFiber(node, renderLanes); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); + if (node === workInProgress) { + return; } - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); - } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; - - { - if (workInProgress.mode & StrictMode) { - disableLogs(); - - try { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - } finally { - reenableLogs(); - } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } + + node = node.return; } - reconcileChildren(null, workInProgress, value, renderLanes); + node.sibling.return = node.return; + node = node.sibling; + } +} - { - validateFunctionComponentInDev(workInProgress, Component); +function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; + + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; } - return workInProgress.child; + row = row.sibling; } + + return lastContentRow; } -function validateFunctionComponentInDev(workInProgress, Component) { +function validateRevealOrder(revealOrder) { { - if (Component) { - if (Component.childContextTypes) { - error( - "%s(...): childContextTypes cannot be defined on a function component.", - Component.displayName || Component.name || "Component" - ); - } - } + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + break; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + case "forward": + case "backward": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + break; + } - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder ); } } + } +} - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentName(Component) || "Unknown"; +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 + '"%s" is not a supported value for tail on . ' + + 'Did you mean "collapsed" or "hidden"?', + tailMode ); + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } - } - - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName4 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { error( - "%s: Function components do not support contextType.", - _componentName4 + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode ); - - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; } } } } -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; - -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes - }; -} +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; -function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { - return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) - }; -} // TODO: Probably should inline this back + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; -function shouldRemainOnFallback( - suspenseContext, - current, - workInProgress, - renderLanes -) { - // If we're already showing a fallback, there are cases where we need to - // remain on that fallback regardless of whether the content has resolved. - // For example, SuspenseList coordinates when nested content appears. - if (current !== null) { - var suspenseState = current.memoizedState; + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); - if (suspenseState === null) { - // Currently showing content. Don't hide it, even if ForceSuspenseFallack - // is true. More precise name might be "ForceRemainSuspenseFallback". - // Note: This is a factoring smell. Can't remain on a fallback if there's - // no fallback to remain on. return false; } - } // Not currently showing content. Consult the Suspense context. + } - return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); + return true; } -function getRemainingWorkInPrimaryTree(current, renderLanes) { - // TODO: Should not remove render lanes that were pinged during this render - return removeLanes(current.childLanes, renderLanes); -} +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (Array.isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; + } + } + } else { + var iteratorFn = getIteratorFn(children); -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - { - if (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; - } - } + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; - var suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { - // Something in this boundary's subtree already suspended. Switch to - // rendering the fallback children. - showFallback = true; - workInProgress.flags &= ~DidCapture; - } else { - // Attempting the main content - if (current === null || current.memoizedState !== null) { - // This is a new mount or this boundary is already showing a fallback state. - // Mark this subtree context as having at least one invisible parent that could - // handle the fallback state. - // Boundaries without fallbacks or should be avoided are not considered since - // they cannot handle preferred fallback states. - if ( - nextProps.fallback !== undefined && - nextProps.unstable_avoidThisFallback !== true - ) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext - ); + _i++; + } + } + } else { + error( + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); + } } } } +} - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense - // boundary's children. This involves some custom reconcilation logic. Two - // main reasons this is so complicated. - // - // First, Legacy Mode has different semantics for backwards compatibility. The - // primary tree will commit in an inconsistent state, so when we do the - // second pass to render the fallback, we do some exceedingly, uh, clever - // hacks to make that not totally break. Like transferring effects and - // deletions from hidden tree. In Concurrent Mode, it's much simpler, - // because we bailout on the primary tree completely and leave it in its old - // state, no effects. Same as what we do for Offscreen (except that - // Offscreen doesn't have the first render pass). - // - // Second is hydration. During hydration, the Suspense fiber has a slightly - // different layout, where the child points to a dehydrated fragment, which - // contains the DOM rendered by the server. - // - // Third, even if you set all that aside, Suspense is like error boundaries in - // that we first we try to render one tree, and if that fails, we render again - // and switch to a different tree. Like a try/catch block. So we have to track - // which branch we're currently rendering. Ideally we would model this using - // a stack. +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; - if (current === null) { - // Initial mount - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.renderingStartTime = 0; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailMode = tailMode; + } +} // This can end up rendering this component multiple passes. +// The first pass splits the children fibers into two sets. A head and tail. +// We first render the head. If anything is in fallback state, we do another +// pass through beginWork to rerender all children (including the tail) with +// the force suspend context. If the first render didn't have anything in +// in fallback state. Then we render each row in the tail one-by-one. +// That happens in the completeWork phase without going back to beginWork. - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; +function updateSuspenseListComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var revealOrder = nextProps.revealOrder; + var tailMode = nextProps.tail; + var newChildren = nextProps.children; + validateRevealOrder(revealOrder); + validateTailOptions(tailMode, revealOrder); + validateSuspenseListChildren(newChildren, revealOrder); + reconcileChildren(current, workInProgress, newChildren, renderLanes); + var suspenseContext = suspenseStackCursor.current; + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); - if (showFallback) { - var fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); - var primaryChildFragment = workInProgress.child; - primaryChildFragment.memoizedState = mountSuspenseOffscreenState( - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return fallbackFragment; - } else if (typeof nextProps.unstable_expectedLoadTime === "number") { - // This is a CPU-bound tree. Skip this tree and show a placeholder to - // unblock the surrounding content. Then immediately retry after the - // initial commit. - var _fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags; - var _primaryChildFragment = workInProgress.child; - _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + if (didSuspendBefore) { + // If we previously forced a fallback, we need to schedule work + // on any nested boundaries to let them know to try to render + // again. This is the same as context updating. + propagateSuspenseContextChange( + workInProgress, + workInProgress.child, renderLanes ); - workInProgress.memoizedState = SUSPENDED_MARKER; // 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; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - { - markSpawnedWork(SomeRetryLane); - } + pushSuspenseContext(workInProgress, suspenseContext); - return _fallbackFragment; - } else { - return mountSuspensePrimaryChildren( - workInProgress, - nextPrimaryChildren, - renderLanes - ); - } + if ((workInProgress.mode & BlockingMode) === NoMode) { + // In legacy mode, SuspenseList doesn't work so we just + // use make it a noop by treating it as the default revealOrder. + workInProgress.memoizedState = null; } else { - // This is an update. - // If the current fiber has a SuspenseState, that means it's already showing - // a fallback. - var prevState = current.memoizedState; - - if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; + switch (revealOrder) { + case "forwards": { + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; - var _fallbackChildFragment = updateSuspenseFallbackChildren( - current, + if (lastContentRow === null) { + // The whole list is part of the tail. + // TODO: We could fast path by just rendering the tail now. + tail = workInProgress.child; + workInProgress.child = null; + } else { + // Disconnect the tail rows after the content row. + // We're going to render them separately later. + tail = lastContentRow.sibling; + lastContentRow.sibling = null; + } + + initSuspenseListRenderState( workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, - renderLanes + false, // isBackwards + tail, + lastContentRow, + tailMode ); + break; + } - 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; + case "backwards": { + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes - ); + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - workInProgress.memoizedState = null; - return _primaryChildFragment4; - } - } else { - // The current tree is not already showing a fallback. - if (showFallback) { - // Timed out. - var _nextFallbackChildren3 = nextProps.fallback; - var _nextPrimaryChildren4 = nextProps.children; + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + + initSuspenseListRenderState( workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes + true, // isBackwards + _tail, + null, // last + tailMode ); + break; + } - 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, + case "together": { + initSuspenseListRenderState( workInProgress, - _nextPrimaryChildren5, - renderLanes + false, // isBackwards + null, // tail + null, // last + undefined ); + break; + } + default: { + // The default reveal order is the same as not having + // a boundary. workInProgress.memoizedState = null; - return _primaryChildFragment6; } } } + + return workInProgress.child; } -function mountSuspensePrimaryChildren( - workInProgress, - primaryChildren, - renderLanes -) { - var mode = workInProgress.mode; - var primaryChildProps = { - mode: "visible", - children: primaryChildren - }; - var primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - renderLanes, - null - ); - primaryChildFragment.return = workInProgress; - workInProgress.child = primaryChildFragment; - return primaryChildFragment; +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + + if (current === null) { + // Portals are special because we don't append the children during mount + // but at commit. Therefore we need to track insertions which the normal + // flow doesn't do during mount. This doesn't happen at the root because + // the root always starts with a "current" with a null child. + // TODO: Consider unifying this with how the root works. + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } + + return workInProgress.child; } -function mountSuspenseFallbackChildren( - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; +var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) { - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; +function updateContextProvider(current, workInProgress, renderLanes) { + var providerType = workInProgress.type; + var context = providerType._context; + var newProps = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + var newValue = newProps.value; - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = 0; - primaryChildFragment.treeBaseDuration = 0; + { + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; + + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + ); + } } - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); - } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null - ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + var providerPropTypes = workInProgress.type.propTypes; + + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + } } - primaryChildFragment.return = workInProgress; - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; + pushProvider(workInProgress, context, newValue); + + if (oldProps !== null) { + var oldValue = oldProps.value; + var changedBits = calculateChangedBits(context, newValue, oldValue); + + if (changedBits === 0) { + // No change. Bailout early if children are the same. + if (oldProps.children === newProps.children && !hasContextChanged()) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + } else { + // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange(workInProgress, context, changedBits, renderLanes); + } + } + + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; } -function createWorkInProgressOffscreenFiber(current, offscreenProps) { - // The props argument to `createWorkInProgress` is `any` typed, so we use this - // wrapper function to constrain it. - return createWorkInProgress(current, offscreenProps); -} +var hasWarnedAboutUsingContextAsConsumer = false; + +function updateContextConsumer(current, workInProgress, renderLanes) { + var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In + // DEV mode, we create a separate object for Context.Consumer that acts + // like a proxy to Context. This proxy object adds unnecessary code in PROD + // so we use the old behaviour (Context.Consumer references Context) to + // reduce size and overhead. The separate object references context via + // a property called "_context", which also gives us the ability to check + // in DEV mode if this property exists or not and warn if it does not. + + { + if (context._context === undefined) { + // This may be because it's a Context (rather than a Consumer). + // Or it may be because it's older React where they're the same thing. + // We only want to warn if we're sure it's a new React. + if (context !== context.Consumer) { + if (!hasWarnedAboutUsingContextAsConsumer) { + hasWarnedAboutUsingContextAsConsumer = true; -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - { - mode: "visible", - children: primaryChildren + error( + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); + } + } + } else { + context = context._context; } - ); - - if ((workInProgress.mode & BlockingMode) === NoMode) { - primaryChildFragment.lanes = renderLanes; } - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = null; + var newProps = workInProgress.pendingProps; + var render = newProps.children; - if (currentFallbackChildFragment !== null) { - // Delete the fallback child fragment - currentFallbackChildFragment.nextEffect = null; - currentFallbackChildFragment.flags = Deletion; - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; + { + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } } - workInProgress.child = primaryChildFragment; - return primaryChildFragment; -} + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; -function updateSuspenseFallbackChildren( - current, - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. - if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was - // already cloned. In legacy mode, the only case where this isn't true is - // when DevTools forces us to display a fallback; we skip the first render - // pass entirely and go straight to rendering the fallback. (In Concurrent - // Mode, SuspenseList can also trigger this scenario, but this is a legacy- - // only codepath.) - workInProgress.child !== currentPrimaryChildFragment - ) { - var progressedPrimaryFragment = workInProgress.child; - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration; - primaryChildFragment.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration; - } // The fallback fiber was added as a deletion effect during the first pass. - // However, since we're going to remain on the fallback, we no longer want - // to delete it. So we need to remove it from the list. Deletions are stored - // on the same list as effects. We want to keep the effects from the primary - // tree. So we copy the primary child fragment's effect list, which does not - // include the fallback deletion effect. +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - var progressedLastEffect = primaryChildFragment.lastEffect; +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - if (progressedLastEffect !== null) { - workInProgress.firstEffect = primaryChildFragment.firstEffect; - workInProgress.lastEffect = progressedLastEffect; - progressedLastEffect.nextEffect = null; - } else { - // TODO: Reset this somewhere else? Lol legacy mode is so weird. - workInProgress.firstEffect = workInProgress.lastEffect = null; - } - } else { - primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - primaryChildProps - ); + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); } - var fallbackChildFragment; + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. - if (currentFallbackChildFragment !== null) { - fallbackChildFragment = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - ); + if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { + // The children don't have any work either. We can skip them. + // TODO: Once we add back resuming, we should check if the children are + // a work-in-progress set. If so, we need to transfer their effects. + return null; } else { - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); // Needs a placement effect because the parent (the Suspense boundary) already - // mounted but this is a new fiber. - - fallbackChildFragment.flags |= Placement; + // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. + cloneChildFibers(current, workInProgress); + return workInProgress.child; } - - fallbackChildFragment.return = workInProgress; - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; } -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - if (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); - } + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - scheduleWorkOnParentPath(fiber.return, renderLanes); -} + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. -function propagateSuspenseContextChange( - workInProgress, - firstChild, - renderLanes -) { - // Mark any Suspense boundaries with fallbacks as having work to do. - // If they were previously forced into fallbacks, they may now be able - // to unblock. - var node = firstChild; + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - if (state !== null) { - scheduleWorkOnFiber(node, renderLanes); + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); } - } else if (node.tag === SuspenseListComponent) { - // If the tail is hidden there might not be an Suspense boundaries - // to schedule work on. In this case we have to schedule it on the - // list itself. - // We don't have to traverse to the children of the list since - // the list will propagate the change when it rerenders. - scheduleWorkOnFiber(node, renderLanes); - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) { - return; - } + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); + } } - node = node.return; + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. + + var deletions = returnFiber.deletions; + + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(current); } - node.sibling.return = node.return; - node = node.sibling; + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + + return newWorkInProgress; } } -function findLastContentRow(firstChild) { - // This is going to find the last row among these children that is already - // showing content on the screen, as opposed to being in fallback state or - // new. If a row has multiple Suspense boundaries, any of them being in the - // fallback state, counts as the whole row being in a fallback state. - // Note that the "rows" will be workInProgress, but any nested children - // will still be current since we haven't rendered them yet. The mounted - // order may not be the same as the new order. We use the new order. - var row = firstChild; - var lastContentRow = null; - - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. - - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; - } +function beginWork(current, workInProgress, renderLanes) { + var updateLanes = workInProgress.lanes; - row = row.sibling; + { + if (workInProgress._debugNeedsRemount && current !== null) { + // This will restart the begin phase with a new fiber. + return remountFiber( + current, + workInProgress, + createFiberFromTypeAndProps( + workInProgress.type, + workInProgress.key, + workInProgress.pendingProps, + workInProgress._debugOwner || null, + workInProgress.mode, + workInProgress.lanes + ) + ); + } } - return lastContentRow; -} + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; -function validateRevealOrder(revealOrder) { - { if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type ) { - didWarnAboutRevealOrder[revealOrder] = true; + // If props or context changed, mark the fiber as having performed work. + // This may be unset if the props are determined to be equal later (memo). + didReceiveUpdate = true; + } else if (!includesSomeLane(renderLanes, updateLanes)) { + didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering + // the begin phase. There's still some bookkeeping we that needs to be done + // in this optimized path, mostly pushing stuff onto the stack. - if (typeof revealOrder === "string") { - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'Use lowercase "%s" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; - break; - } + case HostComponent: + pushHostContext(workInProgress); + break; - case "forward": - case "backward": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'React uses the -s suffix in the spelling. Use "%ss" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + case ClassComponent: { + var Component = workInProgress.type; - break; + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); } - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); + break; + } - break; + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; + + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + pushProvider(workInProgress, context, newValue); + break; } - } else { - error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - } - } - } -} -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - error( - '"%s" is not a supported value for tail on . ' + - 'Did you mean "collapsed" or "hidden"?', - tailMode - ); - } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { - didWarnAboutTailOptions[tailMode] = true; + if (hasChildWork) { + workInProgress.flags |= Update; + } // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode - ); - } - } - } -} + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + break; - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; + case SuspenseComponent: { + var state = workInProgress.memoizedState; - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type - ); + if (state !== null) { + // 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. - return false; - } - } + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; - return true; -} + if (includesSomeLane(renderLanes, primaryChildLanes)) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + } else { + // The primary child fragment does not have pending work marked + // on it + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. -function validateSuspenseListChildren(children, revealOrder) { - { - if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false - ) { - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - if (!validateSuspenseListNestedChild(children[i], i)) { - return; + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + return null; + } + } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } + + break; } - } else { - var iteratorFn = getIteratorFn(children); - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + if (didSuspendBefore) { + if (_hasChildWork) { + // If something was in fallback state last time, and we have all the + // same children then we're still in progressive loading state. + // Something might get unblocked by state updates or retries in the + // tree which will affect the tail. So we need to use the normal + // path to compute the correct tail. + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + + workInProgress.flags |= DidCapture; + } // If nothing suspended before and we're rendering the same children, + // then the tail doesn't matter. Anything new that suspends will work + // in the "together" mode, so we can continue from the state we had. + + var renderState = workInProgress.memoizedState; + + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + renderState.lastEffect = null; + } - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + pushSuspenseContext(workInProgress, suspenseStackCursor.current); - _i++; - } + if (_hasChildWork) { + break; + } else { + // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + return null; } - } else { - error( - 'A single row was passed to a . ' + - "This is not useful since it needs multiple rows. " + - "Did you mean to pass multiple children or an array?", - revealOrder - ); } - } - } - } -} -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - var renderState = workInProgress.memoizedState; + case OffscreenComponent: + case LegacyHiddenComponent: { + // Need to check if the tree still needs to be deferred. This is + // almost identical to the logic used in the normal update path, + // so we'll just enter that. The only difference is we'll bail out + // at the next level instead of this one, because the child props + // have not changed. Which is fine. + // TODO: Probably should refactor `beginWork` to split the bailout + // path from the normal path. I'm tempted to do a labeled break here + // but I won't :) + workInProgress.lanes = NoLanes; + return updateOffscreenComponent(current, workInProgress, renderLanes); + } + } - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering - }; + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } else { + if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + } else { + // An update was scheduled on this fiber, but there are no new props + // nor legacy context. Set this to false. If an update queue or context + // consumer produces a changed value, it will set this to true. Otherwise, + // the component will assume the children have not changed and bail out. + didReceiveUpdate = false; + } + } } else { - // We can reuse the existing object from previous renders. - renderState.isBackwards = isBackwards; - renderState.rendering = null; - renderState.renderingStartTime = 0; - renderState.last = lastContentRow; - renderState.tail = tail; - renderState.tailMode = tailMode; - renderState.lastEffect = lastEffectBeforeRendering; - } -} // This can end up rendering this component multiple passes. -// The first pass splits the children fibers into two sets. A head and tail. -// We first render the head. If anything is in fallback state, we do another -// pass through beginWork to rerender all children (including the tail) with -// the force suspend context. If the first render didn't have anything in -// in fallback state. Then we render each row in the tail one-by-one. -// That happens in the completeWork phase without going back to beginWork. - -function updateSuspenseListComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var revealOrder = nextProps.revealOrder; - var tailMode = nextProps.tail; - var newChildren = nextProps.children; - validateRevealOrder(revealOrder); - validateTailOptions(tailMode, revealOrder); - validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren(current, workInProgress, newChildren, renderLanes); - var suspenseContext = suspenseStackCursor.current; - var shouldForceFallback = hasSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); + didReceiveUpdate = false; + } // Before entering the begin phase, clear pending update priority. + // TODO: This assumes that we're about to evaluate the component and process + // the update queue. However, there's an exception: SimpleMemoComponent + // sometimes bails out later in the begin phase. This indicates that we should + // move this assignment out of the common path and into each branch. - if (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.flags |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.flags & DidCapture) !== NoFlags; + workInProgress.lanes = NoLanes; - if (didSuspendBefore) { - // If we previously forced a fallback, we need to schedule work - // on any nested boundaries to let them know to try to render - // again. This is the same as context updating. - propagateSuspenseContextChange( + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, workInProgress, - workInProgress.child, + workInProgress.type, renderLanes ); } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } - - pushSuspenseContext(workInProgress, suspenseContext); - - if ((workInProgress.mode & BlockingMode) === NoMode) { - // In legacy mode, SuspenseList doesn't work so we just - // use make it a noop by treating it as the default revealOrder. - workInProgress.memoizedState = null; - } else { - switch (revealOrder) { - case "forwards": { - var lastContentRow = findLastContentRow(workInProgress.child); - var tail; - - if (lastContentRow === null) { - // The whole list is part of the tail. - // TODO: We could fast path by just rendering the tail now. - tail = workInProgress.child; - workInProgress.child = null; - } else { - // Disconnect the tail rows after the content row. - // We're going to render them separately later. - tail = lastContentRow.sibling; - lastContentRow.sibling = null; - } - - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode, - workInProgress.lastEffect - ); - break; - } + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateLanes, + renderLanes + ); + } - case "backwards": { - // We're going to find the first row that has existing content. - // At the same time we're going to reverse the list of everything - // we pass in the meantime. That's going to be our tail in reverse - // order. - var _tail = null; - var row = workInProgress.child; - workInProgress.child = null; + case FunctionComponent: { + var _Component = workInProgress.type; + var unresolvedProps = workInProgress.pendingProps; + var resolvedProps = + workInProgress.elementType === _Component + ? unresolvedProps + : resolveDefaultProps(_Component, unresolvedProps); + return updateFunctionComponent( + current, + workInProgress, + _Component, + resolvedProps, + renderLanes + ); + } - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderLanes + ); + } - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect - ); - break; - } + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect - ); - break; - } + case HostComponent: + return updateHostComponent(current, workInProgress, renderLanes); - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; - } - } - } + case HostText: + return updateHostText(); - return workInProgress.child; -} + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); - if (current === null) { - // Portals are special because we don't append the children during mount - // but at commit. Therefore we need to track insertions which the normal - // flow doesn't do during mount. This doesn't happen at the root because - // the root always starts with a "current" with a null child. - // TODO: Consider unifying this with how the root works. - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - return workInProgress.child; -} + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); -var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); + } -function updateContextProvider(current, workInProgress, renderLanes) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; + case Mode: + return updateMode(current, workInProgress, renderLanes); - error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - ); - } - } + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - var providerPropTypes = workInProgress.type.propTypes; + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); - } - } + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); - pushProvider(workInProgress, newValue); + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - if (changedBits === 0) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) + ); + } + } } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange(workInProgress, context, changedBits, renderLanes); + + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateLanes, + renderLanes + ); } - } - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateLanes, + renderLanes + ); + } -var hasWarnedAboutUsingContextAsConsumer = false; + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; -function updateContextConsumer(current, workInProgress, renderLanes) { - var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In - // DEV mode, we create a separate object for Context.Consumer that acts - // like a proxy to Context. This proxy object adds unnecessary code in PROD - // so we use the old behaviour (Context.Consumer references Context) to - // reduce size and overhead. The separate object references context via - // a property called "_context", which also gives us the ability to check - // in DEV mode if this property exists or not and warn if it does not. + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); - { - if (context._context === undefined) { - // This may be because it's a Context (rather than a Consumer). - // Or it may be because it's older React where they're the same thing. - // We only want to warn if we're sure it's a new React. - if (context !== context.Consumer) { - if (!hasWarnedAboutUsingContextAsConsumer) { - hasWarnedAboutUsingContextAsConsumer = true; + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderLanes + ); + } - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); - } - } - } else { - context = context._context; + case SuspenseListComponent: { + return updateSuspenseListComponent(current, workInProgress, renderLanes); } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; + case ScopeComponent: { + break; + } - { - if (typeof render !== "function") { - error( - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ); + case OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); } - } - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; + case LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + } + } { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } +} - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; } -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; } -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; +function hadNoMutationsEffects(current, completedWork) { + var didBailout = current !== null && current.child === completedWork.child; + + if (didBailout) { + return true; } - { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + 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; } - markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. + 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 (!includesSomeLane(renderLanes, workInProgress.childLanes)) { - // The children don't have any work either. We can skip them. - // TODO: Once we add back resuming, we should check if the children are - // a work-in-progress set. If so, we need to transfer their effects. - return null; - } else { - // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - cloneChildFibers(current, workInProgress); - return workInProgress.child; - } -} + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); + } -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(); + } - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + appendInitialChild(parent, _instance); + } else if (node.tag === HostPortal); + else if (node.tag === SuspenseComponent) { + if ((node.flags & Update) !== NoFlags) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + if (newIsHidden) { + var primaryChildParent = node.child; - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildren( + parent, + primaryChildParent, + true, + newIsHidden + ); + } - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); - } + var fallbackChildParent = primaryChildParent.sibling; - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); + if (node.child !== null) { + // Continue traversing like normal + node.child.return = node; + node = node.child; + continue; } + } 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; } - prevSibling.sibling = newWorkInProgress; - } // Delete the old fiber and place the new one. - // Since the old fiber is disconnected, we have to schedule it manually. + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - var last = returnFiber.lastEffect; + node = node.return; + } - if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; + node.sibling.return = node.return; + node = node.sibling; } + }; // An unfortunate fork of appendAllChildren because we have two different parent types. - current.nextEffect = null; - current.flags = Deletion; - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + 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; - return newWorkInProgress; - } -} + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); + } - { - if (workInProgress._debugNeedsRemount && current !== null) { - // This will restart the begin phase with a new fiber. - return remountFiber( - current, - workInProgress, - createFiberFromTypeAndProps( - workInProgress.type, - workInProgress.key, - workInProgress.pendingProps, - workInProgress._debugOwner || null, - workInProgress.mode, - workInProgress.lanes - ) - ); - } - } + appendChildToContainerChildSet(containerChildSet, instance); + } else if (node.tag === HostText) { + var _instance2 = node.stateNode; - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance2 = cloneHiddenTextInstance(); + } - if ( - oldProps !== newProps || - hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: - workInProgress.type !== current.type - ) { - // If props or context changed, mark the fiber as having performed work. - // This may be unset if the props are determined to be equal later (memo). - didReceiveUpdate = true; - } else if (!includesSomeLane(renderLanes, updateLanes)) { - didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering - // the begin phase. There's still some bookkeeping we that needs to be done - // in this optimized path, mostly pushing stuff onto the stack. + appendChildToContainerChildSet(containerChildSet, _instance2); + } else if (node.tag === HostPortal); + else if (node.tag === SuspenseComponent) { + if ((node.flags & Update) !== NoFlags) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; + if (newIsHidden) { + var primaryChildParent = node.child; - case HostComponent: - pushHostContext(workInProgress); - break; + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } - case ClassComponent: { - var Component = workInProgress.type; + var fallbackChildParent = primaryChildParent.sibling; - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } } + } - break; + if (node.child !== null) { + // Continue traversing like normal + node.child.return = node; + node = node.child; + continue; } + } 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. - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; + node = node; - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; + if (node === workInProgress) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + 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); + } + }; - if (hasChildWork) { - workInProgress.flags |= Update; - } // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, + 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 stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); - break; + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - case SuspenseComponent: { - var state = workInProgress.memoizedState; + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; - if (state !== null) { - // 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. + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps + ); + } - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - if (includesSomeLane(renderLanes, primaryChildLanes)) { - // The primary children have pending work. Use the normal path - // to attempt to render the primary children again. - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - } else { - // The primary child fragment does not have pending work marked - // on it - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); // The primary children do not have pending work with sufficient - // priority. Bailout. + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged + ); - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + workInProgress.stateNode = newInstance; - if (child !== null) { - // The fallback children have pending work. Skip over the - // primary children and work on the fallback. - return child.sibling; - } else { - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); - } + 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); + } + }; - break; - } + 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. - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; + } + }; +} - var _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); +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; - if (didSuspendBefore) { - if (_hasChildWork) { - // If something was in fallback state last time, and we have all the - // same children then we're still in progressive loading state. - // Something might get unblocked by state updates or retries in the - // tree which will affect the tail. So we need to use the normal - // path to compute the correct tail. - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - } // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - workInProgress.flags |= DidCapture; - } // If nothing suspended before and we're rendering the same children, - // then the tail doesn't matter. Anything new that suspends will work - // in the "together" mode, so we can continue from the state we had. + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - var renderState = workInProgress.memoizedState; + 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; + } - if (renderState !== null) { - // Reset to the "together" mode in case we've started a different - // update in the past but didn't complete it. - renderState.rendering = null; - renderState.tail = null; - renderState.lastEffect = null; - } + break; + } - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + 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; - if (_hasChildWork) { - break; - } else { - // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. - return null; - } + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; } - case OffscreenComponent: - case LegacyHiddenComponent: { - // Need to check if the tree still needs to be deferred. This is - // almost identical to the logic used in the normal update path, - // so we'll just enter that. The only difference is we'll bail out - // at the next level instead of this one, because the child props - // have not changed. Which is fine. - // TODO: Probably should refactor `beginWork` to split the bailout - // path from the normal path. I'm tempted to do a labeled break here - // but I won't :) - workInProgress.lanes = NoLanes; - return updateOffscreenComponent(current, workInProgress, renderLanes); - } - } + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } else { - if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; + 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 { - // An update was scheduled on this fiber, but there are no new props - // nor legacy context. Set this to false. If an update queue or context - // consumer produces a changed value, it will set this to true. Otherwise, - // the component will assume the children have not changed and bail out. - didReceiveUpdate = false; + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; } + + break; } - } else { - didReceiveUpdate = false; - } // Before entering the begin phase, clear pending update priority. - // TODO: This assumes that we're about to evaluate the component and process - // the update queue. However, there's an exception: SimpleMemoComponent - // sometimes bails out later in the begin phase. This indicates that we should - // move this assignment out of the common path and into each branch. + } +} - workInProgress.lanes = NoLanes; +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderLanes - ); - } + 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; - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateLanes, - renderLanes - ); - } + 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. - case FunctionComponent: { - var _Component = workInProgress.type; - var unresolvedProps = workInProgress.pendingProps; - var resolvedProps = - workInProgress.elementType === _Component - ? unresolvedProps - : resolveDefaultProps(_Component, unresolvedProps); - return updateFunctionComponent( - current, - workInProgress, - _Component, - resolvedProps, - renderLanes - ); - } + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + 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. - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderLanes - ); + _child.return = completedWork; + _child = _child.sibling; + } } - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); - - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); + 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; - case HostText: - return updateHostText(); + 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. - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); + 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. - case HostPortal: - return updatePortalComponent(current, workInProgress, renderLanes); + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + completedWork.subtreeFlags |= subtreeFlags; + } - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + completedWork.childLanes = newChildLanes; + return didBailout; +} - return updateForwardRef( - current, - workInProgress, - type, - _resolvedProps2, - renderLanes - ); - } +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: case Fragment: - return updateFragment(current, workInProgress, renderLanes); - case Mode: - return updateMode(current, workInProgress, renderLanes); - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); + case ClassComponent: { + var Component = workInProgress.type; - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); + if (isContextProvider(Component)) { + popContext(workInProgress); + } - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + bubbleProperties(workInProgress); + return null; + } - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + case HostRoot: { + var fiberRoot = workInProgress.stateNode; - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); - } + 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 (!fiberRoot.hydrate) { + // 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 the container would already be empty). + workInProgress.flags |= Snapshot; } } - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateLanes, - renderLanes - ); + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + return null; } - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateLanes, - renderLanes - ); - } + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } + } else { + if (!newProps) { + if (!(workInProgress.stateNode !== null)) { + throw 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. - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderLanes - ); - } + bubbleProperties(workInProgress); + return null; + } - case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); - } + 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. + } - case FundamentalComponent: { - break; - } + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } - case ScopeComponent: { - break; + bubbleProperties(workInProgress); + return null; } - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); - } + case HostText: { + var newText = newProps; - case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); - } - } + 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. - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + updateHostText$1(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (!(workInProgress.stateNode !== null)) { + throw 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. + } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; -} + var _rootContainerInstance = getRootHostContainer(); -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; -} + var _currentHostContext = getHostContext(); -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; + var _wasHydrated2 = popHydrationState(); -{ - // 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; + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + bubbleProperties(workInProgress); + return null; + } - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - appendInitialChild(parent, instance); - } else if (node.tag === HostText) { - var _instance = node.stateNode; + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(); - } + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. - appendInitialChild(parent, _instance); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.flags & Update) !== NoFlags) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + return workInProgress; + } - if (newIsHidden) { - var primaryChildParent = node.child; + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildren( - parent, - primaryChildParent, - true, - newIsHidden - ); - } + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; + } - var fallbackChildParent = primaryChildParent.sibling; + if (nextDidTimeout && !prevDidTimeout) { + // If this subtree is running in blocking mode we can suspend, + // otherwise we won't suspend. + // 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 & BlockingMode) !== 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; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } - } + 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(); } } + } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; + { + // TODO: Only schedule updates if not prevDidTimeout. + if (nextDidTimeout) { + // If this boundary just timed out, schedule an effect to attach a + // retry listener to the promise. This flag is also used to hide the + // primary children. + workInProgress.flags |= Update; } - } 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; - } + bubbleProperties(workInProgress); - node = node.return; + { + 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 doens't support type casting in combiation with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment2.treeBaseDuration; + } + } + } } - node.sibling.return = node.return; - node = node.sibling; + return null; } - }; // 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; + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } + bubbleProperties(workInProgress); + return null; - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance3 = cloneHiddenTextInstance(); - } + 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; - appendChildToContainerChildSet(containerChildSet, _instance3); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.flags & Update) !== NoFlags) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + if (isContextProvider(_Component)) { + popContext(workInProgress); + } + + bubbleProperties(workInProgress); + return null; + } - if (newIsHidden) { - var primaryChildParent = node.child; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildrenToContainer( - containerChildSet, - primaryChildParent, - true, - newIsHidden - ); - } + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } - var fallbackChildParent = primaryChildParent.sibling; + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } - } - } - } + 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 (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; - } - } 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. + if (!cannotBeSuspended) { + var row = workInProgress.child; - node = node; + while (row !== null) { + var suspended = findFirstSuspended(row); - if (node === workInProgress) { - return; - } + 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 thennables. Instead, we'll transfer its thennables 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. - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + var newThennables = suspended.updateQueue; - node = node.return; - } + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + 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. - node.sibling.return = node.return; - node = node.sibling; - } - }; + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - updateHostContainer = function(workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = workInProgress.firstEffect === null; + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. - 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. + return workInProgress.child; + } - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + row = row.sibling; + } + } - markUpdate(workInProgress); - finalizeContainerChildren(container, newChildSet); - } - }; + 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. - 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. + workInProgress.lanes = SomeRetryLane; - var childrenUnchanged = workInProgress.firstEffect === null; + { + markSpawnedWork(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 (childrenUnchanged && oldProps === newProps) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } + 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 recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; + var _newThennables = _suspended.updateQueue; - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps - ); - } + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.flags |= Update; + } - if (childrenUnchanged && updatePayload === null) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } + cutOffTailIfNeeded(renderState, true); // This might have been modified. - var newInstance = cloneInstance( - currentInstance, - updatePayload, - type, - oldProps, - newProps, - workInProgress, - childrenUnchanged - ); + 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.stateNode = newInstance; + workInProgress.lanes = SomeRetryLane; - 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); - } - }; + { + markSpawnedWork(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; - 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. + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - markUpdate(workInProgress); - } else { - workInProgress.stateNode = current.stateNode; - } - }; -} + renderState.last = renderedTail; + } + } -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; + 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. - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; + var suspenseContext = suspenseStackCursor.current; + + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. - 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; + return next; } - break; + bubbleProperties(workInProgress); + return null; } - 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; + case ScopeComponent: { + break; + } - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; - 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; + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" + ) { + workInProgress.flags |= Update; } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; + } // Don't bubble properties for hidden children. + + if ( + !nextIsHidden || + includesSomeLane(subtreeRenderLanes, OffscreenLane) || + (workInProgress.mode & ConcurrentMode) === NoMode + ) { + bubbleProperties(workInProgress); } - break; + return null; } } -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; + { + 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(workInProgress, renderLanes) { switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - return null; - case ClassComponent: { var Component = workInProgress.type; @@ -15163,6 +16187,18 @@ function completeWork(current, workInProgress, renderLanes) { popContext(workInProgress); } + var flags = workInProgress.flags; + + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + return null; } @@ -15170,1935 +16206,2002 @@ function completeWork(current, workInProgress, renderLanes) { popHostContainer(workInProgress); popTopLevelContextObject(workInProgress); resetWorkInProgressVersions(); - var fiberRoot = workInProgress.stateNode; + var _flags = workInProgress.flags; - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; + if (!((_flags & DidCapture) === NoFlags)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); } - 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(); + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; + } - 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 (!fiberRoot.hydrate) { - // 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 the container would already be empty). - workInProgress.flags |= Snapshot; + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + + case SuspenseComponent: { + popSuspenseContext(workInProgress); + + var _flags2 = workInProgress.flags; + + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); } + + return workInProgress; } - updateHostContainer(workInProgress); return null; } - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + return null; + } - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } - } else { - if (!newProps) { - if (!(workInProgress.stateNode !== null)) { - throw 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. + case HostPortal: + popHostContainer(workInProgress); + return null; - return null; - } + case ContextProvider: + var context = workInProgress.type._context; + popProvider(context, workInProgress); + return null; + + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); + + return null; + + case CacheComponent: + return null; + + default: + return null; + } +} + +function unwindInterruptedWork(interruptedWork, renderLanes) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; + + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } + + break; + } - 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. + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + resetWorkInProgressVersions(); + break; + } - var _wasHydrated = popHydrationState(); + case HostComponent: { + popHostContext(interruptedWork); + break; + } - 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. - } + case HostPortal: + popHostContainer(interruptedWork); + break; - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - return null; - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - case HostText: { - var newText = newProps; + case ContextProvider: + var context = interruptedWork.type._context; + popProvider(context, interruptedWork); + break; - 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. + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(interruptedWork); - updateHostText$1(current, workInProgress, oldText, newText); - } else { - if (typeof newText !== "string") { - if (!(workInProgress.stateNode !== null)) { - throw 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. - } + break; + } +} - var _rootContainerInstance = getRootHostContainer(); +function createCapturedValue(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} - var _currentHostContext = getHostContext(); +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - var _wasHydrated2 = popHydrationState(); +function showErrorDialog(boundary, errorInfo) { + var capturedError = { + componentStack: errorInfo.stack !== null ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + boundary !== null && boundary.tag === ClassComponent + ? boundary.stateNode + : null + }; + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } +function logCapturedError(boundary, errorInfo) { + try { + var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - return null; + if (logError === false) { + return; } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + var error = errorInfo.value; - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + if (error != null && error._suppressLogging) { + if (boundary.tag === ClassComponent) { + // The error is recoverable and was silenced. + // Ignore it and don't print the stack addendum. + // This is handy for testing error boundaries without noise. + return; + } // The error is fatal. Since the silencing might have + // been accidental, we'll surface it anyway. + // However, the browser would have silenced the original error + // so we'll print it first, and then print the stack addendum. - return workInProgress; + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + var componentName = source ? getComponentName(source.type) : null; + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; + var errorBoundaryName = getComponentName(boundary.type); - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); + if (errorBoundaryName) { + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; } - if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in blocking mode we can suspend, - // otherwise we won't suspend. - // 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 & BlockingMode) !== 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; + var combinedMessage = + componentNameMessage + + "\n" + + componentStack + + "\n\n" + + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. + // We don't include the original error message and JS stack because the browser + // has already printed it. Even if the application swallows the error, it is still + // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - 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(); - } - } - } + console["error"](combinedMessage); // Don't transform to our wrapper + } else { + // In production, we print the error directly. + // This will include the message, the JS stack, and anything the browser wants to show. + // We pass the error object instead of custom message so that the browser displays the error natively. + console["error"](error); // Don't transform to our wrapper + } + } catch (e) { + // This method must not throw, or React internal state will get messed up. + // If console.error is overridden, or logCapturedError() shows a dialog that throws, + // we want to report this error outside of the normal stack as a last resort. + // https://github.com/facebook/react/issues/13188 + setTimeout(function() { + throw e; + }); + } +} - { - // TODO: Only schedule updates if not prevDidTimeout. - if (nextDidTimeout) { - // If this boundary just timed out, schedule an effect to attach a - // retry listener to the promise. This flag is also used to hide the - // primary children. - workInProgress.flags |= Update; - } - } +var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; + +function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. + + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". + + update.payload = { + element: null + }; + var error = errorInfo.value; - return null; - } + update.callback = function() { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); + return update; +} - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } +function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - return null; + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; - case ContextProvider: - // Pop provider fiber - popProvider(workInProgress); - return null; + update.payload = function() { + logCapturedError(fiber, errorInfo); + return getDerivedStateFromError(error$1); + }; + } - 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; + var inst = fiber.stateNode; - if (isContextProvider(_Component)) { - popContext(workInProgress); + if (inst !== null && typeof inst.componentDidCatch === "function") { + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); } - return null; - } - - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + if (typeof getDerivedStateFromError !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromError is + // not defined. + markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - return null; + logCapturedError(fiber, errorInfo); } - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); - 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 (typeof getDerivedStateFromError !== "function") { + // If componentDidCatch is the only error boundary method defined, + // then it needs to call setState to recover from errors. + // If no state update is scheduled then the boundary will swallow the error. + if (!includesSomeLane(fiber.lanes, SyncLane)) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" + ); + } + } + } + }; + } else { + update.callback = function() { + markFailedErrorBoundaryForHotReloading(fiber); + }; + } - if (!cannotBeSuspended) { - var row = workInProgress.child; + return update; +} - while (row !== null) { - var suspended = findFirstSuspended(row); +function attachPingListener(root, wakeable, lanes) { + // Attach a listener to the promise to "ping" the root and retry. But only if + // one does not already exist for the lanes we're currently rendering (which + // acts like a "thread ID" here). + var pingCache = root.pingCache; + var threadIDs; - 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 thennables. Instead, we'll transfer its thennables 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. + if (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap$1(); + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } else { + threadIDs = pingCache.get(wakeable); - var newThennables = suspended.updateQueue; + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } - if (newThennables !== null) { - workInProgress.updateQueue = newThennables; - workInProgress.flags |= Update; - } // Rerender the whole list, but this time, we'll force fallbacks - // to stay in place. - // Reset the effect list before doing the second pass since that's now invalid. + if (!threadIDs.has(lanes)) { + // Memoize using the thread ID to prevent redundant listeners. + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); + } +} - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } +function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes +) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + if ( + value !== null && + typeof value === "object" && + typeof value.then === "function" + ) { + // This is a wakeable. + var wakeable = value; + // A legacy mode Suspense quirk, only relevant to hook components. - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + var tag = sourceFiber.tag; - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } + if ( + (sourceFiber.mode & BlockingMode) === NoMode && + (tag === FunctionComponent || + tag === ForwardRef || + tag === SimpleMemoComponent) + ) { + var currentSource = sourceFiber.alternate; - row = row.sibling; - } - } + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; + } + } - 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. + var hasInvisibleParentBoundary = hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ); // Schedule the nearest Suspense to re-render the timed out view. - workInProgress.lanes = SomeRetryLane; + var _workInProgress = returnFiber; - { - markSpawnedWork(SomeRetryLane); - } - } + do { + if ( + _workInProgress.tag === SuspenseComponent && + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) + ) { + // Found the nearest boundary. + // Stash the promise on the boundary fiber. If the boundary times out, we'll + // attach another listener to flip the boundary back to its normal state. + var wakeables = _workInProgress.updateQueue; + + if (wakeables === null) { + var updateQueue = new Set(); + updateQueue.add(wakeable); + _workInProgress.updateQueue = updateQueue; } 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); + wakeables.add(wakeable); + } // If the boundary is outside of blocking mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. In the commit phase, we'll schedule a + // subsequent synchronous update to re-render the Suspense. + // + // Note: It doesn't matter whether the component that suspended was + // inside a blocking mode tree. If the Suspense is outside of it, we + // should *not* suspend the commit. + // + // If the suspense boundary suspended itself suspended, we don't have to + // do this trick because nothing was partially started. We can just + // directly do a second pass over the fallback in this render and + // pretend we meant to render that directly. - 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. + if ( + (_workInProgress.mode & BlockingMode) === NoMode && + _workInProgress !== returnFiber + ) { + _workInProgress.flags |= DidCapture; + sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. + // But we shouldn't call any lifecycle methods or callbacks. Remove + // all lifecycle effect tags. - var _newThennables = _suspended.updateQueue; + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; + if (sourceFiber.tag === ClassComponent) { + var currentSourceFiber = sourceFiber.alternate; + + if (currentSourceFiber === null) { + // This is a new mount. Change the tag so it's not mistaken for a + // completed class component. For example, we should not call + // componentWillUnmount if it is deleted. + sourceFiber.tag = IncompleteClassComponent; + } else { + // When we try rendering again, we should not reuse the current fiber, + // since it's known to be in an inconsistent state. Use a force update to + // prevent a bail out. + var update = createUpdate(NoTimestamp, SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update); } + } // The source fiber did not complete. Mark it with Sync priority to + // indicate that it still has pending work. - cutOffTailIfNeeded(renderState, true); // This might have been modified. + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We need to delete the row we just rendered. - // Reset the effect list to what it was before we rendered this - // child. The nested children have already appended themselves. - var lastEffect = (workInProgress.lastEffect = - renderState.lastEffect); // Remove any effects that were appended after this point. + return; + } // Confirmed that the boundary is in a concurrent mode tree. Continue + // with the normal suspend path. + // + // After this we'll use a set of heuristics to determine whether this + // render pass will run to completion or restart or "suspend" the commit. + // The actual logic for this is spread out in different places. + // + // This first principle is that if we're going to suspend when we complete + // a root, then we should also restart if we get an update or ping that + // might unsuspend it, and vice versa. The only reason to suspend is + // because you think you might want to restart before committing. However, + // it doesn't make sense to restart only while in the period we're suspended. + // + // Restarting too aggressively is also not good because it starves out any + // intermediate loading state. So we use heuristics to determine when. + // Suspense Heuristics + // + // If nothing threw a Promise or all the same fallbacks are already showing, + // then don't suspend/restart. + // + // If this is an initial render of a new tree of Suspense boundaries and + // those trigger a fallback, then don't suspend/restart. We want to ensure + // that we can show the initial loading state as quickly as possible. + // + // If we hit a "Delayed" case, such as when we'd switch from content back into + // a fallback, then we should always suspend/restart. Transitions apply + // to this case. If none is defined, JND is used instead. + // + // If we're already showing a fallback and it gets "retried", allowing us to show + // another level, but there's still an inner boundary that would show a fallback, + // then we suspend/restart for 500ms since the last time we showed a fallback + // anywhere in the tree. This effectively throttles progressive loading into a + // consistent train of commits. This also gives us an opportunity to restart to + // get to the completed state slightly earlier. + // + // If there's ambiguity due to batching it's resolved in preference of: + // 1) "delayed", 2) "initial render", 3) "retry". + // + // We want to ensure that a "busy" state doesn't get force committed. We want to + // ensure that new initial loading states can commit as soon as possible. - if (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + attachPingListener(root, wakeable, rootRenderLanes); + _workInProgress.flags |= ShouldCapture; + _workInProgress.lanes = rootRenderLanes; + return; + } // This boundary already captured during this render. Continue to the next + // boundary. - 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 = _workInProgress.return; + } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. + // TODO: Use invariant so the message is stripped in prod? - workInProgress.lanes = SomeRetryLane; + value = new Error( + (getComponentName(sourceFiber.type) || "A React component") + + " suspended while rendering, but no fallback UI was specified.\n" + + "\n" + + "Add a component higher in the tree to " + + "provide a loading indicator or placeholder to display." + ); + } // We didn't find a boundary that could handle this type of exception. Start + // over and traverse parent path again, this time treating the exception + // as an error. - { - markSpawnedWork(SomeRetryLane); - } - } - } + renderDidError(); + value = createCapturedValue(value, sourceFiber); + var workInProgress = returnFiber; - 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; + do { + switch (workInProgress.tag) { + case HostRoot: { + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); - renderState.last = renderedTail; - } + enqueueCapturedUpdate(workInProgress, _update); + return; } - 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.lastEffect = workInProgress.lastEffect; - 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. + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; - var suspenseContext = suspenseStackCursor.current; + if ( + (workInProgress.flags & DidCapture) === NoFlags && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + var _lane = pickArbitraryLane(rootRenderLanes); - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state - return next; - } + var _update2 = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); - return null; - } + enqueueCapturedUpdate(workInProgress, _update2); + return; + } - case FundamentalComponent: { - break; + break; } - case ScopeComponent: { - break; - } + workInProgress = workInProgress.return; + } while (workInProgress !== null); +} - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - if (current !== null) { - var _nextState = workInProgress.memoizedState; - var _prevState = current.memoizedState; - var prevIsHidden = _prevState !== null; - var nextIsHidden = _nextState !== null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - if ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" - ) { - workInProgress.flags |= Update; - } - } +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +var nextEffect = null; - return null; - } - } +var callComponentWillUnmountWithTimer = function(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + instance.componentWillUnmount(); } -} - -function unwindWork(workInProgress, renderLanes) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; +}; // Capture errors so they don't interrupt unmounting. - if (isContextProvider(Component)) { - popContext(workInProgress); - } +function safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance +) { + { + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance + ); - var flags = workInProgress.flags; + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, unmountError); + } + } +} - if (flags & ShouldCapture) { - workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; +function safelyDetachRef(current, nearestMountedAncestor) { + var ref = current.ref; - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); + if (ref !== null) { + if (typeof ref === "function") { + { + { + invokeGuardedCallback(null, ref, null, null); } - return workInProgress; + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, refError); + } } - - return null; + } else { + ref.current = null; } + } +} - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - var _flags = workInProgress.flags; - - if (!((_flags & DidCapture) === NoFlags)) { - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - - workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; - return workInProgress; - } +function safelyCallDestroy(current, nearestMountedAncestor, destroy) { + { + invokeGuardedCallback(null, destroy, null); - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, error); } + } +} - case SuspenseComponent: { - popSuspenseContext(workInProgress); +var focusedInstanceHandle = null; +var shouldFireAfterActiveInstanceBlur = false; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = prepareForCommit(root.containerInfo); + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber - var _flags2 = workInProgress.flags; + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + focusedInstanceHandle = null; + return shouldFire; +} - if (_flags2 & ShouldCapture) { - workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. +function commitBeforeMutationEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + var deletions = fiber.deletions; - return workInProgress; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var deletion = deletions[i]; + commitBeforeMutationEffectsDeletion(deletion); } - - return null; } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been - // caught by a nested boundary. If not, it should bubble through. + var child = fiber.child; - return null; + if ( + (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && + child !== null + ) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitBeforeMutationEffects_complete(); } - - case HostPortal: - popHostContainer(workInProgress); - return null; - - case ContextProvider: - popProvider(workInProgress); - return null; - - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(workInProgress); - return null; - - default: - return null; } } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; +function commitBeforeMutationEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitBeforeMutationEffectsOnFiber, + null, + fiber + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - break; + resetCurrentFiber(); } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - resetWorkInProgressVersions(); - break; - } + var sibling = fiber.sibling; - case HostComponent: { - popHostContext(interruptedWork); - break; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - case HostPortal: - popHostContainer(interruptedWork); - break; - - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; - - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; + nextEffect = fiber.return; + } +} - case ContextProvider: - popProvider(interruptedWork); - break; +function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(interruptedWork); - break; + if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { + // Check to see if the focused element was inside of a hidden (Suspense) subtree. + // TODO: Move this out of the hot path using a dedicated effect tag. + if ( + finishedWork.tag === SuspenseComponent && + isSuspenseBoundaryBeingHidden(current, finishedWork) && + doesFiberContain(finishedWork, focusedInstanceHandle) + ) { + shouldFireAfterActiveInstanceBlur = true; + } } -} -function createCapturedValue(value, source) { - // If the value is an error, call this function immediately after it is thrown - // so the stack is accurate. - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(finishedWork); -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + break; + } -function showErrorDialog(boundary, errorInfo) { - var capturedError = { - componentStack: errorInfo.stack !== null ? errorInfo.stack : "", - error: errorInfo.value, - errorBoundary: - boundary !== null && boundary.tag === ClassComponent - ? boundary.stateNode - : null - }; - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + case ClassComponent: { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + var instance = finishedWork.stateNode; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. -function logCapturedError(boundary, errorInfo) { - try { - var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (logError === false) { - return; - } + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - var error = errorInfo.value; + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - if (true) { - var source = errorInfo.source; - var stack = errorInfo.stack; - var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - if (error != null && error._suppressLogging) { - if (boundary.tag === ClassComponent) { - // The error is recoverable and was silenced. - // Ignore it and don't print the stack addendum. - // This is handy for testing error boundaries without noise. - return; - } // The error is fatal. Since the silencing might have - // been accidental, we'll surface it anyway. - // However, the browser would have silenced the original error - // so we'll print it first, and then print the stack addendum. + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 - } + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } + + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } - var componentName = source ? getComponentName(source.type) : null; - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; - var errorBoundaryName = getComponentName(boundary.type); + break; + } - if (errorBoundaryName) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); - } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + case HostRoot: { + break; } - var combinedMessage = - componentNameMessage + - "\n" + - componentStack + - "\n\n" + - ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. - // We don't include the original error message and JS stack because the browser - // has already printed it. Even if the application swallows the error, it is still - // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + break; - console["error"](combinedMessage); // Don't transform to our wrapper - } else { - // In production, we print the error directly. - // This will include the message, the JS stack, and anything the browser wants to show. - // We pass the error object instead of custom message so that the browser displays the error natively. - console["error"](error); // Don't transform to our wrapper + default: { + { + 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." + ); + } + } } - } catch (e) { - // This method must not throw, or React internal state will get messed up. - // If console.error is overridden, or logCapturedError() shows a dialog that throws, - // we want to report this error outside of the normal stack as a last resort. - // https://github.com/facebook/react/issues/13188 - setTimeout(function() { - throw e; - }); + + resetCurrentFiber(); } } -var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; +function commitBeforeMutationEffectsDeletion(deletion) { + // TODO (effects) It would be nice to avoid calling doesFiberContain() + // Maybe we can repurpose one of the subtreeFlags positions for this instead? + // Use it to store which part of the tree the focused instance is in? + // This assumes we can safely determine that instance during the "render" phase. + if (doesFiberContain(deletion, focusedInstanceHandle)) { + shouldFireAfterActiveInstanceBlur = true; + } +} -function createRootErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor +) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property - // being called "element". + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - update.payload = { - element: null - }; - var error = errorInfo.value; + do { + if ((effect.tag & flags) === flags) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; - update.callback = function() { - onUncaughtError(error); - logCapturedError(fiber, errorInfo); - }; + if (destroy !== undefined) { + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + } + } - return update; + effect = effect.next; + } while (effect !== firstEffect); + } } -function createClassErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); - update.tag = CaptureUpdate; - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - - if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; - - update.payload = function() { - logCapturedError(fiber, errorInfo); - return getDerivedStateFromError(error$1); - }; - } +function commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - var inst = fiber.stateNode; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - { - markFailedErrorBoundaryForHotReloading(fiber); - } + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); - if (typeof getDerivedStateFromError !== "function") { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromError is - // not defined. - markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + { + var destroy = effect.destroy; - logCapturedError(fiber, errorInfo); - } + if (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; - var error$1 = errorInfo.value; - var stack = errorInfo.stack; - this.componentDidCatch(error$1, { - componentStack: stack !== null ? stack : "" - }); + if (destroy === null) { + addendum = + " You returned null. If your effect does not require clean " + + "up, return undefined (or nothing)."; + } else if (typeof destroy.then === "function") { + addendum = + "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + "useEffect(() => {\n" + + " async function fetchData() {\n" + + " // You can await here\n" + + " const response = await MyAPI.getData(someId);\n" + + " // ...\n" + + " }\n" + + " fetchData();\n" + + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } - { - if (typeof getDerivedStateFromError !== "function") { - // If componentDidCatch is the only error boundary method defined, - // then it needs to call setState to recover from errors. - // If no state update is scheduled then the boundary will swallow the error. - if (!includesSomeLane(fiber.lanes, SyncLane)) { error( - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s", + addendum ); } } } - }; - } else { - update.callback = function() { - markFailedErrorBoundaryForHotReloading(fiber); - }; - } - return update; + effect = effect.next; + } while (effect !== firstEffect); + } } -function attachPingListener(root, wakeable, lanes) { - // Attach a listener to the promise to "ping" the root and retry. But only if - // one does not already exist for the lanes we're currently rendering (which - // acts like a "thread ID" here). - var pingCache = root.pingCache; - var threadIDs; +function commitLayoutEffectOnFiber( + finishedRoot, + current, + finishedWork, + committedLanes +) { + if ((finishedWork.flags & (Update | Callback)) !== NoFlags) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent 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. + { + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } - if (pingCache === null) { - pingCache = root.pingCache = new PossiblyWeakMap$1(); - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } else { - threadIDs = pingCache.get(wakeable); + break; + } + + case ClassComponent: { + var instance = finishedWork.stateNode; + + if (finishedWork.flags & Update) { + if (current === null) { + // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } + + { + instance.componentDidMount(); + } + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } + + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + + var updateQueue = finishedWork.updateQueue; + + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + + commitUpdateQueue(finishedWork, updateQueue, instance); + } - if (threadIDs === undefined) { - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } - } + break; + } - if (!threadIDs.has(lanes)) { - // Memoize using the thread ID to prevent redundant listeners. - threadIDs.add(lanes); - var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); - wakeable.then(ping, ping); - } -} + case HostRoot: { + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; + + if (_updateQueue !== null) { + var _instance = null; + + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; + + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + } -function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes -) { - // The source fiber did not complete. - sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + break; + } - if ( - value !== null && - typeof value === "object" && - typeof value.then === "function" - ) { - // This is a wakeable. - var wakeable = value; + case HostComponent: { + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. - if ((sourceFiber.mode & BlockingMode) === NoMode) { - // Reset the memoizedState to what it was before we attempted - // to render it. - var currentSource = sourceFiber.alternate; + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(); + } - if (currentSource) { - sourceFiber.updateQueue = currentSource.updateQueue; - sourceFiber.memoizedState = currentSource.memoizedState; - sourceFiber.lanes = currentSource.lanes; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; + break; } - } - - var hasInvisibleParentBoundary = hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ); // Schedule the nearest Suspense to re-render the timed out view. - var _workInProgress = returnFiber; + case HostText: { + // We have no life-cycles associated with text. + break; + } - do { - if ( - _workInProgress.tag === SuspenseComponent && - shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) - ) { - // Found the nearest boundary. - // Stash the promise on the boundary fiber. If the boundary times out, we'll - // attach another listener to flip the boundary back to its normal state. - var wakeables = _workInProgress.updateQueue; + case HostPortal: { + // We have no life-cycles associated with portals. + break; + } - if (wakeables === null) { - var updateQueue = new Set(); - updateQueue.add(wakeable); - _workInProgress.updateQueue = updateQueue; - } else { - wakeables.add(wakeable); - } // If the boundary is outside of blocking mode, we should *not* - // suspend the commit. Pretend as if the suspended component rendered - // null and keep rendering. In the commit phase, we'll schedule a - // subsequent synchronous update to re-render the Suspense. - // - // Note: It doesn't matter whether the component that suspended was - // inside a blocking mode tree. If the Suspense is outside of it, we - // should *not* suspend the commit. + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); + var phase = current === null ? "mount" : "update"; + + if (typeof onRender === "function") { + { + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + } + } + } - if ((_workInProgress.mode & BlockingMode) === NoMode) { - _workInProgress.flags |= DidCapture; - sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. - // But we shouldn't call any lifecycle methods or callbacks. Remove - // all lifecycle effect tags. + break; + } - sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + case SuspenseComponent: { + break; + } - if (sourceFiber.tag === ClassComponent) { - var currentSourceFiber = sourceFiber.alternate; + case SuspenseListComponent: + case IncompleteClassComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + break; - if (currentSourceFiber === null) { - // This is a new mount. Change the tag so it's not mistaken for a - // completed class component. For example, we should not call - // componentWillUnmount if it is deleted. - sourceFiber.tag = IncompleteClassComponent; - } else { - // When we try rendering again, we should not reuse the current fiber, - // since it's known to be in an inconsistent state. Use a force update to - // prevent a bail out. - var update = createUpdate(NoTimestamp, SyncLane); - update.tag = ForceUpdate; - enqueueUpdate(sourceFiber, update); - } - } // The source fiber did not complete. Mark it with Sync priority to - // indicate that it still has pending work. + default: { + 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." + ); + } + } + } - sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. + { + if (finishedWork.flags & Ref) { + commitAttachRef(finishedWork); + } + } +} - return; - } // Confirmed that the boundary is in a concurrent mode tree. Continue - // with the normal suspend path. - // - // After this we'll use a set of heuristics to determine whether this - // render pass will run to completion or restart or "suspend" the commit. - // The actual logic for this is spread out in different places. - // - // This first principle is that if we're going to suspend when we complete - // a root, then we should also restart if we get an update or ping that - // might unsuspend it, and vice versa. The only reason to suspend is - // because you think you might want to restart before committing. However, - // it doesn't make sense to restart only while in the period we're suspended. - // - // Restarting too aggressively is also not good because it starves out any - // intermediate loading state. So we use heuristics to determine when. - // Suspense Heuristics - // - // If nothing threw a Promise or all the same fallbacks are already showing, - // then don't suspend/restart. - // - // If this is an initial render of a new tree of Suspense boundaries and - // those trigger a fallback, then don't suspend/restart. We want to ensure - // that we can show the initial loading state as quickly as possible. - // - // If we hit a "Delayed" case, such as when we'd switch from content back into - // a fallback, then we should always suspend/restart. Transitions apply - // to this case. If none is defined, JND is used instead. - // - // If we're already showing a fallback and it gets "retried", allowing us to show - // another level, but there's still an inner boundary that would show a fallback, - // then we suspend/restart for 500ms since the last time we showed a fallback - // anywhere in the tree. This effectively throttles progressive loading into a - // consistent train of commits. This also gives us an opportunity to restart to - // get to the completed state slightly earlier. - // - // If there's ambiguity due to batching it's resolved in preference of: - // 1) "delayed", 2) "initial render", 3) "retry". - // - // We want to ensure that a "busy" state doesn't get force committed. We want to - // ensure that new initial loading states can commit as soon as possible. +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; - attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; - _workInProgress.lanes = rootRenderLanes; - return; - } // This boundary already captured during this render. Continue to the next - // boundary. + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; - _workInProgress = _workInProgress.return; - } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. - // TODO: Use invariant so the message is stripped in prod? + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; - value = new Error( - (getComponentName(sourceFiber.type) || "A React component") + - " suspended while rendering, but no fallback UI was specified.\n" + - "\n" + - "Add a component higher in the tree to " + - "provide a loading indicator or placeholder to display." - ); - } // We didn't find a boundary that could handle this type of exception. Start - // over and traverse parent path again, this time treating the exception - // as an error. + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag - renderDidError(); - value = createCapturedValue(value, sourceFiber); - var workInProgress = returnFiber; + if (typeof ref === "function") { + { + ref(instanceToUse); + } + } else { + { + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentName(finishedWork.type) + ); + } + } - do { - switch (workInProgress.tag) { - case HostRoot: { - var _errorInfo = value; - workInProgress.flags |= ShouldCapture; - var lane = pickArbitraryLane(rootRenderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + ref.current = instanceToUse; + } + } +} - var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); +function commitDetachRef(current) { + var currentRef = current.ref; - enqueueCapturedUpdate(workInProgress, _update); - return; + if (currentRef !== null) { + if (typeof currentRef === "function") { + { + 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 - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var instance = workInProgress.stateNode; +function commitUnmount( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + onCommitUnmount(current); + + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + var updateQueue = current.updateQueue; - if ( - (workInProgress.flags & DidCapture) === NoFlags && - (typeof ctor.getDerivedStateFromError === "function" || - (instance !== null && - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance))) - ) { - workInProgress.flags |= ShouldCapture; + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - var _lane = pickArbitraryLane(rootRenderLanes); + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; - var _update2 = createClassErrorUpdate( - workInProgress, - errorInfo, - _lane - ); + if (destroy !== undefined) { + if ((tag & Layout) !== NoFlags$1) { + { + safelyCallDestroy(current, nearestMountedAncestor, destroy); + } + } + } - enqueueCapturedUpdate(workInProgress, _update2); - return; + effect = effect.next; + } while (effect !== firstEffect); } + } - break; + return; } - workInProgress = workInProgress.return; - } while (workInProgress !== null); -} - -var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + case ClassComponent: { + safelyDetachRef(current, nearestMountedAncestor); + var instance = current.stateNode; -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance + ); + } -var callComponentWillUnmountWithTimer = function(current, instance) { - instance.props = current.memoizedProps; - instance.state = current.memoizedState; + return; + } - { - instance.componentWillUnmount(); - } -}; // Capture errors so they don't interrupt unmounting. + case HostComponent: { + safelyDetachRef(current, nearestMountedAncestor); + return; + } -function safelyCallComponentWillUnmount(current, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance - ); + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. + { + emptyPortalContainer(current); + } - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + return; } - } -} - -function safelyDetachRef(current) { - var ref = current.ref; - if (ref !== null) { - if (typeof ref === "function") { - { - { - invokeGuardedCallback(null, ref, null, null); - } + case DehydratedFragment: { + return; + } - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); - } - } - } else { - ref.current = null; + case ScopeComponent: { + return; } } } -function safelyCallDestroy(current, destroy) { - { - invokeGuardedCallback(null, destroy, null); +function commitNestedUnmounts( + finishedRoot, + root, + nearestMountedAncestor, + renderPriorityLevel +) { + // 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; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, error); + 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; } - } -} -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { + if (node === root) { return; } - case ClassComponent: { - if (finishedWork.flags & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - var instance = finishedWork.stateNode; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; + } - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + node = node.return; + } - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); + node.sibling.return = node.return; + node = node.sibling; + } +} - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; +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. + // It also prevents events from bubbling from within disconnected components. + // + // Ideally, we should also clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. + // This child itself will be GC:ed when the parent updates the next time. + // + // Note that we can't clear child or sibling pointers yet. + // They're needed for passive effects and for findDOMNode. + // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). + // + // Don't reset the alternate yet, either. We need that so we can detach the + // alternate's fields in the passive phase. Clearing the return pointer is + // sufficient for findDOMNode semantics. + fiber.return = null; +} - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); +function detachFiberAfterEffects(fiber) { + // Null out fields to improve GC for references that may be lingering (e.g. DevTools). + // Note that we already cleared the return pointer in detachFiberMutation(). + fiber.alternate = null; + fiber.child = null; + fiber.deletions = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.sibling = null; + fiber.stateNode = null; + fiber.updateQueue = null; - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); - } - } + { + fiber._debugOwner = null; + } +} - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } - } +function emptyPortalContainer(current) { + var portal = current.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); +} +function commitContainer(finishedWork) { + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: { return; } - case HostRoot: { + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; return; } + } - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types - 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 commitDeletion( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current, nearestMountedAncestor); + } + + var alternate = current.alternate; + detachFiberMutation(current); + + if (alternate !== null) { + detachFiberMutation(alternate); } +} +function commitWork(current, finishedWork) { { - 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." - ); - } -} + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // 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. + { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } -function commitHookEffectListUnmount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + case Profiler: { + return; + } - do { - if ((effect.tag & tag) === tag) { - // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } - if (destroy !== undefined) { - destroy(); - } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; } - effect = effect.next; - } while (effect !== firstEffect); + case HostRoot: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + return; + } + } + + commitContainer(finishedWork); + return; } } -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + if (newState !== null) { + markCommitTimeOfFallback(); + } +} - do { - if ((effect.tag & tag) === tag) { - // Mount - var create = effect.create; - effect.destroy = create(); +function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; - { - var destroy = effect.destroy; + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; - if (destroy !== undefined && typeof destroy !== "function") { - var addendum = void 0; + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + } - if (destroy === null) { - addendum = - " You returned null. If your effect does not require clean " + - "up, return undefined (or nothing)."; - } else if (typeof destroy.then === "function") { - addendum = - "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + - "Instead, write the async function inside your effect " + - "and call it immediately:\n\n" + - "useEffect(() => {\n" + - " async function fetchData() {\n" + - " // You can await here\n" + - " const response = await MyAPI.getData(someId);\n" + - " // ...\n" + - " }\n" + - " fetchData();\n" + - "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + - "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; - } else { - addendum = " You returned: " + destroy; - } + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - error( - "An effect function must not return anything besides a function, " + - "which is used for clean-up.%s", - addendum - ); + if (!retryCache.has(wakeable)) { + { + if (wakeable.__reactDoNotTraceInteractions !== true) { + retry = tracing.unstable_wrap(retry); } } - } - - effect = effect.next; - } while (effect !== firstEffect); - } -} - -function schedulePassiveEffects(finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; - - do { - var _effect = effect, - next = _effect.next, - tag = _effect.tag; - if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); - enqueuePendingPassiveHookEffectMount(finishedWork, effect); + retryCache.add(wakeable); + wakeable.then(retry, retry); } - - effect = next; - } while (effect !== firstEffect); + }); } -} +} // This function detects when a Suspense boundary goes from visible to hidden. +// It returns false if the boundary is already hidden. +// TODO: Use an effect tag. -function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - // At this point layout effects have already been destroyed (during mutation phase). - // This is done to prevent 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. - { - commitHookEffectListMount(Layout | HasEffect, finishedWork); - } +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + if (current !== null) { + var oldState = current.memoizedState; - schedulePassiveEffects(finishedWork); - return; + if (oldState === null || oldState.dehydrated !== null) { + var newState = finishedWork.memoizedState; + return newState !== null && newState.dehydrated === null; } + } - case ClassComponent: { - var instance = finishedWork.stateNode; + return false; +} - if (finishedWork.flags & Update) { - if (current === null) { - // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + nextEffect = firstChild; + commitMutationEffects_begin(root, renderPriorityLevel); +} - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } +function commitMutationEffects_begin(root, renderPriorityLevel) { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - { - instance.componentDidMount(); - } - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + var deletions = fiber.deletions; - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + { + invokeGuardedCallback( + null, + commitDeletion, + null, + root, + childToDelete, + fiber, + renderPriorityLevel + ); - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(childToDelete, fiber, error); } } - } // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. + } + } - var updateQueue = finishedWork.updateQueue; + var child = fiber.child; - if (updateQueue !== null) { - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitMutationEffects_complete(root, renderPriorityLevel); + } + } +} - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. +function commitMutationEffects_complete(root, renderPriorityLevel) { + while (nextEffect !== null) { + var fiber = nextEffect; + + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitMutationEffectsOnFiber, + null, + fiber, + root, + renderPriorityLevel + ); - commitUpdateQueue(finishedWork, updateQueue, instance); + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - return; + resetCurrentFiber(); } - case HostRoot: { - // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. - var _updateQueue = finishedWork.updateQueue; + var sibling = fiber.sibling; - if (_updateQueue !== null) { - var _instance = null; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; + nextEffect = fiber.return; + } +} - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } +function commitMutationEffectsOnFiber(finishedWork, root, renderPriorityLevel) { + var flags = finishedWork.flags; - commitUpdateQueue(finishedWork, _updateQueue, _instance); - } + if (flags & Ref) { + var current = finishedWork.alternate; - return; + if (current !== null) { + commitDetachRef(current); } + } // 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. - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. + var primaryFlags = flags & (Placement | Update | Hydrating); - if (current === null && finishedWork.flags & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - commitMount(); - } + 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. - return; + finishedWork.flags &= ~Placement; + break; } - case HostText: { - // We have no life-cycles associated with text. - return; - } + case PlacementAndUpdate: { + // inserted, before any life-cycles like componentDidMount gets called. - case HostPortal: { - // We have no life-cycles associated with portals. - return; + finishedWork.flags &= ~Placement; // Update + + var _current = finishedWork.alternate; + commitWork(_current, finishedWork); + break; } - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + case Hydrating: { + finishedWork.flags &= ~Hydrating; + break; + } - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - current === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } - } - } + case HydratingAndUpdate: { + finishedWork.flags &= ~Hydrating; // Update - return; + var _current2 = finishedWork.alternate; + commitWork(_current2, finishedWork); + break; } - case SuspenseComponent: { - return; + case Update: { + var _current3 = finishedWork.alternate; + commitWork(_current3, finishedWork); + break; } - - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - case OffscreenComponent: - case LegacyHiddenComponent: - 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 commitLayoutEffects(finishedWork, root, committedLanes) { + nextEffect = finishedWork; + commitLayoutEffects_begin(finishedWork, root, committedLanes); } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; + if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + } + } +} - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; +function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + while (nextEffect !== null) { + var fiber = nextEffect; - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag + if ((fiber.flags & LayoutMask) !== NoFlags) { + var current = fiber.alternate; - if (typeof ref === "function") { { - ref(instanceToUse); - } - } else { - { - if (!ref.hasOwnProperty("current")) { - error( - "Unexpected ref object provided for %s. " + - "Use either a ref-setter function or React.createRef().", - getComponentName(finishedWork.type) - ); + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitLayoutEffectOnFiber, + null, + root, + current, + fiber, + committedLanes + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } + + resetCurrentFiber(); } + } - ref.current = instanceToUse; + if (fiber === subtreeRoot) { + nextEffect = null; + return; } - } -} -function commitDetachRef(current) { - var currentRef = current.ref; + var sibling = fiber.sibling; - if (currentRef !== null) { - if (typeof currentRef === "function") { - { - currentRef(null); - } - } else { - currentRef.current = null; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - } -} // 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, renderPriorityLevel) { - onCommitUnmount(current); + nextEffect = fiber.return; + } +} - switch (current.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - var updateQueue = current.updateQueue; +function commitPassiveMountEffects(root, finishedWork) { + nextEffect = finishedWork; + commitPassiveMountEffects_begin(finishedWork, root); +} - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; +function commitPassiveMountEffects_begin(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitPassiveMountEffects_complete(subtreeRoot, root); + } + } +} - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; +function commitPassiveMountEffects_complete(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; - if (destroy !== undefined) { - if ((tag & Passive$1) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(current, effect); - } else { - { - safelyCallDestroy(current, destroy); - } - } - } + if ((fiber.flags & Passive) !== NoFlags) { + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitPassiveMountOnFiber, + null, + root, + fiber + ); - effect = effect.next; - } while (effect !== firstEffect); + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - } - - return; - } - - case ClassComponent: { - safelyDetachRef(current); - var instance = current.stateNode; - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, instance); + resetCurrentFiber(); } - - return; } - case HostComponent: { - safelyDetachRef(current); + if (fiber === subtreeRoot) { + nextEffect = null; return; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - emptyPortalContainer(current); - } + var sibling = fiber.sibling; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; return; } - case FundamentalComponent: { - return; - } + nextEffect = fiber.return; + } +} - case DehydratedFragment: { - return; - } +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); + } - case ScopeComponent: { - return; + break; } } } -function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { - // 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); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. +function commitPassiveUnmountEffects(firstChild) { + nextEffect = firstChild; + commitPassiveUnmountEffects_begin(); +} - 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; - } +function commitPassiveUnmountEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; + var child = fiber.child; - if (node === root) { - return; - } + if ((nextEffect.flags & ChildDeletion) !== NoFlags) { + var deletions = fiber.deletions; - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + nextEffect = fiberToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + fiberToDelete, + fiber + ); // Now that passive effects have been processed, it's safe to detach lingering pointers. - node = node.return; - } + var alternate = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); - node.sibling.return = node.return; - node = node.sibling; - } -} + if (alternate !== null) { + detachFiberAfterEffects(alternate); + } + } -function detachFiberMutation(fiber) { - // Cut off the return pointers to disconnect it from the tree. Ideally, we - // should clear the child pointer of the parent alternate to let this - // get GC:ed but we don't know which for sure which parent is the current - // one so we'll settle for GC:ing the subtree of this child. This child - // itself will be GC:ed when the parent updates the next time. - // Note: we cannot null out sibling here, otherwise it can cause issues - // with findDOMNode and how it requires the sibling field to carry out - // traversal in a later effect. See PR #16820. We now clear the sibling - // field after effects, see: detachFiberAfterEffects. - // - // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. - // It may be required if the current component is an error boundary, - // and one of its descendants throws while unmounting a passive effect. - fiber.alternate = null; - fiber.child = null; - fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.return = null; - fiber.updateQueue = null; + nextEffect = fiber; + } + } - { - fiber._debugOwner = null; + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffects_complete(); + } } } -function emptyPortalContainer(current) { - var portal = current.stateNode; - var containerInfo = portal.containerInfo; - var emptyChildSet = createContainerChildSet(containerInfo); -} +function commitPassiveUnmountEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; -function commitContainer(finishedWork) { - switch (finishedWork.tag) { - case ClassComponent: - case HostComponent: - case HostText: - case FundamentalComponent: { - return; + if ((fiber.flags & Passive) !== NoFlags) { + setCurrentFiber(fiber); + commitPassiveUnmountOnFiber(fiber); + resetCurrentFiber(); } - case HostRoot: - case HostPortal: { - var portalOrRoot = finishedWork.stateNode; - var containerInfo = portalOrRoot.containerInfo, - pendingChildren = portalOrRoot.pendingChildren; + var sibling = fiber.sibling; + + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; 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." - ); + nextEffect = fiber.return; } } -function commitDeletion(finishedRoot, current, renderPriorityLevel) { +function commitPassiveUnmountOnFiber(finishedWork) { { - // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current); + finishedWork.flags &= ~PassiveUnmountPendingDev; + var alternate = finishedWork.alternate; + + if (alternate !== null) { + alternate.flags &= ~PassiveUnmountPendingDev; + } } - var alternate = current.alternate; - detachFiberMutation(current); + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount( + Passive$1 | HasEffect, + finishedWork, + finishedWork.return + ); + } - if (alternate !== null) { - detachFiberMutation(alternate); + break; + } } } -function commitWork(current, finishedWork) { - { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - // 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. - { - commitHookEffectListUnmount(Layout | HasEffect, finishedWork); - } +function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + deletedSubtreeRoot, + nearestMountedAncestor +) { + while (nextEffect !== null) { + var fiber = nextEffect; // Deletion effects fire in parent -> child order + // TODO: Check if fiber has a PassiveStatic flag - return; - } + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag - case Profiler: { - return; - } + if (child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ); + } + } +} - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; - } +function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot +) { + while (nextEffect !== null) { + var fiber = nextEffect; - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } + if (fiber === deletedSubtreeRoot) { + nextEffect = null; + return; + } - case HostRoot: { - break; - } + var sibling = fiber.sibling; - case OffscreenComponent: - case LegacyHiddenComponent: { - return; - } + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - commitContainer(finishedWork); - return; + nextEffect = fiber.return; } } -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; +function commitPassiveUnmountInsideDeletedTreeOnFiber( + current, + nearestMountedAncestor +) { + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); + } - if (newState !== null) { - markCommitTimeOfFallback(); + break; + } } } -function attachSuspenseRetryListeners(finishedWork) { - // If this boundary just timed out, then it will have a set of wakeables. - // For each wakeable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. - var wakeables = finishedWork.updateQueue; - - if (wakeables !== null) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - - if (retryCache === null) { - retryCache = finishedWork.stateNode = new PossiblyWeakSet(); - } - - wakeables.forEach(function(wakeable) { - // Memoize using the boundary fiber to prevent redundant listeners. - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - - if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } - - retryCache.add(wakeable); - wakeable.then(retry, retry); - } - }); - } -} // This function detects when a Suspense boundary goes from visible to hidden. -// It returns false if the boundary is already hidden. -// TODO: Use an effect tag. +var didWarnWrongReturnPointer = false; -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - if (current !== null) { - var oldState = current.memoizedState; +function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { + { + if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { + didWarnWrongReturnPointer = true; - if (oldState === null || oldState.dehydrated !== null) { - var newState = finishedWork.memoizedState; - return newState !== null && newState.dehydrated === null; + 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 - return false; + fiber.return = expectedReturnFiber; } var COMPONENT_TYPE = 0; @@ -17180,8 +18283,7 @@ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. -var workInProgressRootPingedLanes = NoLanes; -var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train +var workInProgressRootPingedLanes = NoLanes; // The most recent time we committed a fallback. This lets us ensure a train // model where we don't commit new loading states in too quick succession. var globalMostRecentFallbackTime = 0; @@ -17200,16 +18302,13 @@ function resetRenderTimer() { function getRenderTargetTime() { return workInProgressRootRenderTargetTime; } -var nextEffect = null; var hasUncaughtError = false; var firstUncaughtError = null; -var legacyErrorBoundariesThatAlreadyFailed = null; +var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; -var pendingPassiveEffectsRenderPriority = NoPriority$1; +var pendingPassiveEffectsRenderPriority = NoPriority; var pendingPassiveEffectsLanes = NoLanes; -var pendingPassiveHookEffectsMount = []; -var pendingPassiveHookEffectsUnmount = []; var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; @@ -17227,13 +18326,10 @@ var spawnedWorkDuringRender = null; // If two updates are scheduled within the s // between the first and second call. var currentEventTime = NoTimestamp; -var currentEventWipLanes = NoLanes; -var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. +var currentEventTransitionLane = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. // We warn about state updates for unmounted components differently in this case. var isFlushingPassiveEffects = false; -var focusedInstanceHandle = null; -var shouldFireAfterActiveInstanceBlur = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -17258,63 +18354,41 @@ function requestUpdateLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 + return getCurrentPriorityLevel() === ImmediatePriority ? SyncLane : SyncBatchedLane; } // The algorithm for assigning an update to a lane should be stable for all - // updates at the same priority within the same event. To do this, the inputs - // to the algorithm must be the same. For example, we use the `renderLanes` - // to avoid choosing a lane that is already in the middle of rendering. - // - // However, the "included" lanes could be mutated in between updates in the - // same event, like if you perform an update inside `flushSync`. Or any other - // code path that might call `prepareFreshStack`. - // - // The trick we use is to cache the first of each of these inputs within an - // event. Then reset the cached values once we can be sure the event is over. - // Our heuristic for that is whenever we enter a concurrent work loop. - // - // We'll do the same for `currentEventPendingLanes` below. - - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; - } var isTransition = requestCurrentTransition() !== NoTransition; if (isTransition) { - if (currentEventPendingLanes !== NoLanes) { - currentEventPendingLanes = - mostRecentlyUpdatedRoot !== null - ? mostRecentlyUpdatedRoot.pendingLanes - : NoLanes; + if (currentEventTransitionLane === NoLane) { + currentEventTransitionLane = claimNextTransitionLane(); } - return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); + return currentEventTransitionLane; } // TODO: Remove this dependency on the Scheduler priority. // To do that, we're replacing it with an update lane priority. - var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. - // This couples React to the Scheduler internals, so we're replacing it - // with the currentUpdateLanePriority above. As an example of how this - // could be problematic, if we're not inside `Scheduler.runWithPriority`, - // then we'll get the priority of the current running Scheduler task, - // which is probably not what we want. + var schedulerPriority = getCurrentPriorityLevel(); // Find the correct lane based on priorities. Ideally, this would just be + // the update lane priority, but for now we're also checking for discrete + // updates and falling back to the scheduler priority. var lane; if ( // TODO: Temporary. We're removing the concept of discrete updates. (executionContext & DiscreteEventContext) !== NoContext && - schedulerPriority === UserBlockingPriority$1 + schedulerPriority === UserBlockingPriority ) { - lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); + lane = findUpdateLane(InputDiscreteLanePriority); } else { - var schedulerLanePriority = schedulerPriorityToLanePriority( - schedulerPriority - ); - - lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); + { + var schedulerLanePriority = schedulerPriorityToLanePriority( + schedulerPriority + ); + lane = findUpdateLane(schedulerLanePriority); + } } return lane; @@ -17330,16 +18404,12 @@ function requestRetryLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 + return getCurrentPriorityLevel() === ImmediatePriority ? SyncLane : SyncBatchedLane; } // See `requestUpdateLane` for explanation of `currentEventWipLanes` - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; - } - - return findRetryLane(currentEventWipLanes); + return claimNextRetryLane(); } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -17412,8 +18482,8 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority$1 || - priorityLevel === ImmediatePriority$1) + (priorityLevel === UserBlockingPriority || + priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority // discrete update per root so we can flush them early, if needed. @@ -17426,13 +18496,9 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, lane); - } // We use this when assigning a lane for a transition inside - // `requestUpdateLane`. We assume it's the same as the root being updated, - // since in the common case of a single root app it probably is. If it's not - // the same root, then it's not a huge deal, we just might batch more stuff - // together more than necessary. + } - mostRecentlyUpdatedRoot = root; + return root; } // This is split into a separate function so we can mark a fiber with pending // work without treating it as a typical update that originates from an event; // e.g. retrying a Suspense boundary isn't an update, but it does schedule work @@ -17454,7 +18520,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { ) { warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - } // Walk the parent path to the root and update the child expiration time. + } // Walk the parent path to the root and update the child lanes. var node = sourceFiber; var parent = sourceFiber.return; @@ -17483,6 +18549,20 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { } else { return null; } +} + +function isInterleavedUpdate(fiber, lane) { + return ( + // 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 && + (fiber.mode & BlockingMode) !== 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 + // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled. + deferRenderPhaseUpdateToNextBatch + ); } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the priority // of the existing task is the same as the priority of the next level that the @@ -17506,22 +18586,36 @@ function ensureRootIsScheduled(root, currentTime) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); - root.callbackNode = null; - root.callbackPriority = NoLanePriority; } + root.callbackNode = null; + root.callbackPriority = NoLanePriority; return; } // Check if there's an existing task. We may be able to reuse it. - if (existingCallbackNode !== null) { - var existingCallbackPriority = root.callbackPriority; + var existingCallbackPriority = root.callbackPriority; - if (existingCallbackPriority === newCallbackPriority) { - // The priority hasn't changed. We can reuse the existing task. Exit. - return; - } // The priority changed. Cancel the existing callback. We'll schedule a new - // one below. + if (existingCallbackPriority === newCallbackPriority) { + { + // If we're going to re-use an existing task, it needs to exist. + // Assume that discrete update microtasks are non-cancellable and null. + // TODO: Temporary until we confirm this warning is not fired. + if ( + existingCallbackNode == null && + existingCallbackPriority !== InputDiscreteLanePriority && + existingCallbackPriority !== SyncLanePriority + ) { + error( + "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue." + ); + } + } // The priority hasn't changed. We can reuse the existing task. Exit. + + return; + } + if (existingCallbackNode != null) { + // Cancel the existing callback. We'll schedule a new one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. @@ -17530,12 +18624,11 @@ function ensureRootIsScheduled(root, currentTime) { if (newCallbackPriority === SyncLanePriority) { // Special case: Sync React callbacks are scheduled on a special // internal queue - newCallbackNode = scheduleSyncCallback( - performSyncWorkOnRoot.bind(null, root) - ); + scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + newCallbackNode = null; } else if (newCallbackPriority === SyncBatchedLanePriority) { newCallbackNode = scheduleCallback( - ImmediatePriority$1, + ImmediatePriority, performSyncWorkOnRoot.bind(null, root) ); } else { @@ -17553,12 +18646,11 @@ function ensureRootIsScheduled(root, currentTime) { } // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root) { - // Since we know we're in a React event, we can clear the current +function performConcurrentWorkOnRoot(root, didTimeout) { // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; + currentEventTransitionLane = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { throw Error("Should not already be working."); @@ -17588,24 +18680,22 @@ function performConcurrentWorkOnRoot(root) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; + } // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + + if (didTimeout) { + // Something expired. Flush synchronously until there's no expired + // work left. + markRootExpired(root, lanes); // This will schedule a synchronous callback. + + ensureRootIsScheduled(root, now()); + return null; } var exitStatus = renderRootConcurrent(root, lanes); - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack(root, NoLanes); - } else if (exitStatus !== RootIncomplete) { + if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. @@ -17797,26 +18887,9 @@ function performSyncWorkOnRoot(root) { // rendering it before rendering the rest of the expired work. lanes = workInProgressRootRenderLanes; exitStatus = renderRootSync(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // Note that this only happens when part of the tree is rendered - // concurrently. If the whole tree is rendered synchronously, then there - // are no interleaved events. - lanes = getNextLanes(root, lanes); - exitStatus = renderRootSync(root, lanes); - } } else { - lanes = getNextLanes(root, NoLanes); + lanes = getNextLanes(root, NoLanes); // Because we don't cancel synchronous tasks, sometimes more than one + exitStatus = renderRootSync(root, lanes); } @@ -17894,7 +18967,7 @@ function flushSync(fn, a) { { try { if (fn) { - return runWithPriority(ImmediatePriority$1, fn.bind(null, a)); + return runWithPriority(ImmediatePriority, fn.bind(null, a)); } else { return undefined; } @@ -17950,6 +19023,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootSkippedLanes = NoLanes; workInProgressRootUpdatedLanes = NoLanes; workInProgressRootPingedLanes = NoLanes; + enqueueInterleavedUpdates(); { spawnedWorkDuringRender = null; @@ -18273,47 +19347,6 @@ function completeUnitOfWork(unitOfWork) { workInProgress = next; return; } - - resetChildLanes(completedWork); - - if ( - returnFiber !== null && // Do not append effects to parents if a sibling failed to complete - (returnFiber.flags & Incomplete) === NoFlags - ) { - // Append all the effects of the subtree and this fiber onto the effect - // list of the parent. The completion order of the children affects the - // side-effect order. - if (returnFiber.firstEffect === null) { - returnFiber.firstEffect = completedWork.firstEffect; - } - - if (completedWork.lastEffect !== null) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork.firstEffect; - } - - returnFiber.lastEffect = completedWork.lastEffect; - } // If this fiber had side-effects, we append it AFTER the children's - // side-effects. We can perform certain side-effects earlier if needed, - // by doing multiple passes over the effect list. We don't want to - // schedule our own side-effect on our own list because if end up - // reusing children we'll schedule this effect onto itself since we're - // at the end. - - var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect - // list. PerformedWork effect is read by React DevTools but shouldn't be - // committed. - - if (flags > PerformedWork) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork; - } else { - returnFiber.firstEffect = completedWork; - } - - returnFiber.lastEffect = completedWork; - } - } } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -18346,9 +19379,10 @@ function completeUnitOfWork(unitOfWork) { } if (returnFiber !== null) { - // Mark the parent fiber as incomplete and clear its effect list. - returnFiber.firstEffect = returnFiber.lastEffect = null; + // Mark the parent fiber as incomplete and clear its subtree flags. returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags; + returnFiber.deletions = null; } } @@ -18370,88 +19404,10 @@ function completeUnitOfWork(unitOfWork) { } } -function resetChildLanes(completedWork) { - if ( - // TODO: Move this check out of the hot path by moving `resetChildLanes` - // to switch statement in `completeWork`. - (completedWork.tag === LegacyHiddenComponent || - completedWork.tag === OffscreenComponent) && - completedWork.memoizedState !== null && - !includesSomeLane(subtreeRenderLanes, OffscreenLane) && - (completedWork.mode & ConcurrentMode) !== NoLanes - ) { - // The children of this component are hidden. Don't bubble their - // expiration times. - return; - } - - var newChildLanes = NoLanes; // 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; // 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. - - var shouldBubbleActualDurations = - completedWork.alternate === null || - completedWork.child !== completedWork.alternate.child; - var child = completedWork.child; - - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - - if (shouldBubbleActualDurations) { - actualDuration += child.actualDuration; - } - - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - var isTimedOutSuspense = - completedWork.tag === SuspenseComponent && - completedWork.memoizedState !== null; - - if (isTimedOutSuspense) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var primaryChildFragment = completedWork.child; - - if (primaryChildFragment !== null) { - treeBaseDuration -= primaryChildFragment.treeBaseDuration; - } - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; - - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - _child = _child.sibling; - } - } - - completedWork.childLanes = newChildLanes; -} - function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); runWithPriority( - ImmediatePriority$1, + ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); return null; @@ -18491,7 +19447,8 @@ function commitRootImpl(root, renderPriorityLevel) { } // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. - root.callbackNode = null; // Update the first and last pending times on this root. The new first + root.callbackNode = null; + root.callbackPriority = NoLanePriority; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); @@ -18513,27 +19470,39 @@ function commitRootImpl(root, renderPriorityLevel) { workInProgressRoot = null; workInProgress = null; workInProgressRootRenderLanes = NoLanes; - } // Get the list of effects. - - var firstEffect; - - if (finishedWork.flags > PerformedWork) { - // A fiber's effect list consists only of its children, not itself. So if - // the root has an effect, we need to add it to the end of the list. The - // resulting list is the set that would belong to the root's parent, if it - // had one; that is, all the effects in the tree including the root. - if (finishedWork.lastEffect !== null) { - finishedWork.lastEffect.nextEffect = finishedWork; - firstEffect = finishedWork.firstEffect; - } else { - firstEffect = finishedWork; - } - } else { - // There is no effect on the root. - firstEffect = finishedWork.firstEffect; - } + } // If there are pending passive effects, schedule a callback to process them. + // Do this as early as possible, so it is queued before anything else that + // might get scheduled in the commit phase. (See #16714.) + // TODO: Delete all other places that schedule the passive effect callback + // They're redundant. - if (firstEffect !== null) { + if ( + (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || + (finishedWork.flags & PassiveMask) !== NoFlags + ) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + }); + } + } // Check if there are any effects in the whole tree. + // TODO: This is left over from the effect list implementation, where we had + // to check for the existence of `firstEffect` to satsify Flow. I think the + // only other reason this optimization exists is because it affects profiling. + // Reconsider whether this is necessary. + + var subtreeHasEffects = + (finishedWork.subtreeFlags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + var rootHasEffect = + (finishedWork.flags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + + if (subtreeHasEffects || rootHasEffect) { var prevExecutionContext = executionContext; executionContext |= CommitContext; var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles @@ -18541,62 +19510,22 @@ function commitRootImpl(root, renderPriorityLevel) { ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass // of the effect list for each phase: all mutation effects come before all // layout effects, and so on. - // The first phase a "before mutation" phase. We use this phase to read the - // state of the host tree right before we mutate it. This is where - // getSnapshotBeforeUpdate is called. - - focusedInstanceHandle = prepareForCommit(root.containerInfo); - shouldFireAfterActiveInstanceBlur = false; - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitBeforeMutationEffects, null); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); // We no longer need to track the active instance fiber + // The first phase a "before mutation" phase. We use this phase to read the + // state of the host tree right before we mutate it. This is where + // getSnapshotBeforeUpdate is called. - focusedInstanceHandle = null; + var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects( + root, + finishedWork + ); { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); - } // The next phase is the mutation phase, where we mutate the host tree. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback( - null, - commitMutationEffects, - null, - root, - renderPriorityLevel - ); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error = clearCaughtError(); + } - captureCommitPhaseError(nextEffect, _error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); + commitMutationEffects(root, renderPriorityLevel, finishedWork); resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after // the mutation phase, so that the previous tree is still current during @@ -18604,29 +19533,8 @@ function commitRootImpl(root, renderPriorityLevel) { // work is current during componentDidMount/Update. root.current = finishedWork; // The next phase is the layout phase, where we call effects that read - // the host tree after it's been mutated. The idiomatic use case for this is - // layout, but class component lifecycles also fire here for legacy reasons. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error2 = clearCaughtError(); - - captureCommitPhaseError(nextEffect, _error2); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); - - nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an + commitLayoutEffects(finishedWork, root, lanes); // opportunity to paint. requestPaint(); @@ -18656,22 +19564,6 @@ function commitRootImpl(root, renderPriorityLevel) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; pendingPassiveEffectsRenderPriority = renderPriorityLevel; - } else { - // We are done with the effect chain at this point so let's clear the - // nextEffect pointers to assist with GC. If we have passive effects, we'll - // clear this in flushPassiveEffects. - nextEffect = firstEffect; - - while (nextEffect !== null) { - var nextNextEffect = nextEffect.nextEffect; - nextEffect.nextEffect = null; - - if (nextEffect.flags & Deletion) { - detachFiberAfterEffects(nextEffect); - } - - nextEffect = nextNextEffect; - } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root @@ -18709,9 +19601,9 @@ function commitRootImpl(root, renderPriorityLevel) { } } - if (remainingLanes === SyncLane) { - // Count the number of times the root synchronously re-renders without + if (includesSomeLane(remainingLanes, SyncLane)) { // finishing. If there are too many, it indicates an infinite update loop. + if (root === rootWithNestedUpdates) { nestedUpdateCount++; } else { @@ -18729,9 +19621,9 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var _error3 = firstUncaughtError; + var error = firstUncaughtError; firstUncaughtError = null; - throw _error3; + throw error; } if ((executionContext & LegacyUnbatchedContext) !== NoContext) { @@ -18747,149 +19639,14 @@ function commitRootImpl(root, renderPriorityLevel) { return null; } -function commitBeforeMutationEffects() { - while (nextEffect !== null) { - var current = nextEffect.alternate; - - if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { - if ((nextEffect.flags & Deletion) !== NoFlags) { - if (doesFiberContain(nextEffect, focusedInstanceHandle)) { - shouldFireAfterActiveInstanceBlur = true; - } - } else { - // TODO: Move this out of the hot path using a dedicated effect tag. - if ( - nextEffect.tag === SuspenseComponent && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) - ) { - shouldFireAfterActiveInstanceBlur = true; - } - } - } - - var flags = nextEffect.flags; - - if ((flags & Snapshot) !== NoFlags) { - setCurrentFiber(nextEffect); - commitBeforeMutationLifeCycles(current, nextEffect); - resetCurrentFiber(); - } - - if ((flags & Passive) !== NoFlags) { - // If there are passive effects, schedule a callback to flush at - // the earliest opportunity. - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } - } - - nextEffect = nextEffect.nextEffect; - } -} - -function commitMutationEffects(root, renderPriorityLevel) { - // TODO: Should probably move the bulk of this function to commitWork. - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & Ref) { - var current = nextEffect.alternate; - - if (current !== null) { - commitDetachRef(current); - } - } // 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 | Deletion | 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. - - nextEffect.flags &= ~Placement; - break; - } - - case PlacementAndUpdate: { - // inserted, before any life-cycles like componentDidMount gets called. - - nextEffect.flags &= ~Placement; // Update - - var _current = nextEffect.alternate; - commitWork(_current, nextEffect); - break; - } - - case Hydrating: { - nextEffect.flags &= ~Hydrating; - break; - } - - case HydratingAndUpdate: { - nextEffect.flags &= ~Hydrating; // Update - - var _current2 = nextEffect.alternate; - commitWork(_current2, nextEffect); - break; - } - - case Update: { - var _current3 = nextEffect.alternate; - commitWork(_current3, nextEffect); - break; - } - - case Deletion: { - commitDeletion(root, nextEffect); - break; - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } -} - -function commitLayoutEffects(root, committedLanes) { - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & (Update | Callback)) { - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); - } - - { - if (flags & Ref) { - commitAttachRef(nextEffect); - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } -} - function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { + if (pendingPassiveEffectsRenderPriority !== NoPriority) { var priorityLevel = - pendingPassiveEffectsRenderPriority > NormalPriority$1 - ? NormalPriority$1 + pendingPassiveEffectsRenderPriority > NormalPriority + ? NormalPriority : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoPriority$1; + pendingPassiveEffectsRenderPriority = NoPriority; { return runWithPriority(priorityLevel, flushPassiveEffectsImpl); @@ -18898,42 +19655,6 @@ function flushPassiveEffects() { return false; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - - { - fiber.flags |= PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags |= PassiveUnmountPendingDev; - } - } - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} - -function invokePassiveEffectCreate(effect) { - var create = effect.create; - effect.destroy = create(); -} function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { @@ -18955,97 +19676,9 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called - // before ANY passive effect create functions are called. - // Otherwise effects in sibling components might interfere with each other. - // e.g. a destroy function in one component may unintentionally override a ref - // value set by a create function in another component. - // Layout effects have the same constraint. - // First pass: Destroy stale passive effects. - - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - - for (var i = 0; i < unmountEffects.length; i += 2) { - var _effect = unmountEffects[i]; - var fiber = unmountEffects[i + 1]; - var destroy = _effect.destroy; - _effect.destroy = undefined; - - { - fiber.flags &= ~PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags &= ~PassiveUnmountPendingDev; - } - } - - if (typeof destroy === "function") { - { - setCurrentFiber(fiber); - - { - invokeGuardedCallback(null, destroy, null); - } - - if (hasCaughtError()) { - if (!(fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(fiber, error); - } - - resetCurrentFiber(); - } - } - } // Second pass: Create new passive effects. - - var mountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - - for (var _i = 0; _i < mountEffects.length; _i += 2) { - var _effect2 = mountEffects[_i]; - var _fiber = mountEffects[_i + 1]; - - { - setCurrentFiber(_fiber); - - { - invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); - } - - if (hasCaughtError()) { - if (!(_fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var _error4 = clearCaughtError(); - - captureCommitPhaseError(_fiber, _error4); - } - - resetCurrentFiber(); - } - } // Note: This currently assumes there are no passive effects on the root fiber - // because the root is not part of its own effect list. - // This could change in the future. - - var effect = root.current.firstEffect; - - while (effect !== null) { - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC - - effect.nextEffect = null; - - if (effect.flags & Deletion) { - detachFiberAfterEffects(effect); - } - - effect = nextNextEffect; - } + var prevInteractions = pushInteractions(root); + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects { popInteractions(prevInteractions); @@ -19102,19 +19735,23 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); return; } - var fiber = sourceFiber.return; + var fiber = null; + + { + fiber = sourceFiber.return; + } while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -19125,7 +19762,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$1, sourceFiber); var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); enqueueUpdate(fiber, update); var eventTime = requestEventTime(); @@ -19135,24 +19772,6 @@ function captureCommitPhaseError(sourceFiber, error) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, SyncLane); - } else { - // This component has already been unmounted. - // We can't schedule any follow up work for the root because the fiber is already unmounted, - // but we can still call the log-only boundary so the error isn't swallowed. - // - // TODO This is only a temporary bandaid for the old reconciler fork. - // We can delete this special case once the new fork is merged. - if ( - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance) - ) { - try { - instance.componentDidCatch(error, errorInfo); - } catch (errorToIgnore) { - // TODO Ignore this error? Rethrow it? - // This is kind of an edge case. - } - } } return; @@ -19161,6 +19780,22 @@ function captureCommitPhaseError(sourceFiber, error) { fiber = fiber.return; } + + { + // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning + // will fire for errors that are thrown by destroy functions inside deleted + // trees. What it should instead do is propagate the error to the parent of + // the deleted tree. In the meantime, do not add this warning to the + // allowlist; this is only for our internal use. + error( + "Internal React error: Attempted to capture a commit phase error " + + "inside a detached tree. This indicates a bug in React. Likely " + + "causes include deleting the same fiber more than once, committing an " + + "already-finished tree, or an inconsistent return pointer.\n\n" + + "Error message:\n\n%s", + error$1 + ); + } } function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; @@ -19213,6 +19848,8 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { // suspended it has resolved, which means at least part of the tree was // likely unblocked. Try rendering again, at a new expiration time. if (retryLane === NoLane) { + // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? retryLane = requestRetryLane(boundaryFiber); } // TODO: Special case idle priority? @@ -19381,11 +20018,29 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } // If there are pending passive effects unmounts for this Fiber, - // we can assume that they would have prevented this update. + } - if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { - return; + if ((fiber.flags & PassiveStatic) !== NoFlags) { + var updateQueue = fiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if (effect.destroy !== undefined) { + if ((effect.tag & Passive$1) !== NoFlags$1) { + return; + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. @@ -19473,14 +20128,23 @@ var beginWork$1; invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); if (hasCaughtError()) { - var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. - // Rethrow this error instead of the original one. + var replayError = clearCaughtError(); - throw replayError; - } else { - // This branch is reachable if the render phase is impure. - throw originalError; - } + if ( + typeof replayError === "object" && + replayError !== null && + replayError._suppressLogging && + typeof originalError === "object" && + originalError !== null && + !originalError._suppressLogging + ) { + // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. + originalError._suppressLogging = true; + } + } // We always throw the original error in case the second render pass is not idempotent. + // This can happen if a memoized function or CommonJS module doesn't throw after first invokation. + + throw originalError; } }; } @@ -19666,7 +20330,7 @@ function startWorkOnPendingInteractions(root, lanes) { subscriber.onWorkStarted(interactions, threadID); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } @@ -19688,7 +20352,7 @@ function finishPendingInteractions(root, committedLanes) { } } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } finally { @@ -19710,7 +20374,7 @@ function finishPendingInteractions(root, committedLanes) { subscriber.onInteractionScheduledWorkCompleted(interaction); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } @@ -19729,11 +20393,6 @@ function shouldForceFlushFallbacksInDEV() { var actingUpdatesScopeDepth = 0; -function detachFiberAfterEffects(fiber) { - fiber.sibling = null; - fiber.stateNode = null; -} - var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. var failedBoundaries = null; @@ -20210,9 +20869,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.mode = mode; // Effects this.flags = NoFlags; - this.nextEffect = null; - this.firstEffect = null; - this.lastEffect = null; + this.subtreeFlags = NoFlags; + this.deletions = null; this.lanes = NoLanes; this.childLanes = NoLanes; this.alternate = null; @@ -20339,11 +20997,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.type = current.type; // We already have an alternate. // Reset the effect tag. - workInProgress.flags = NoFlags; // The effect list is no longer valid. + workInProgress.flags = NoFlags; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; { // We intentionally reset, rather than copy, actualDuration & actualStartTime. @@ -20353,8 +21010,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; } - } + } // Reset all effects except static ones. + // Static effects are not specific to a render. + workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -20411,13 +21070,10 @@ function resetWorkInProgress(workInProgress, renderLanes) { // when they should be reading from current and writing to workInProgress. // We assume pendingProps, index, key, ref, return are still untouched to // avoid doing another reconciliation. - // Reset the effect tag but keep any Placement tags, since that's something + // Reset the effect flags but keep any Placement tags, since that's something // that child fiber is setting, not the reconciliation. - workInProgress.flags &= Placement; // The effect list is no longer valid. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; var current = workInProgress.alternate; if (current === null) { @@ -20425,6 +21081,7 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = NoLanes; workInProgress.lanes = renderLanes; workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags; workInProgress.memoizedProps = null; workInProgress.memoizedState = null; workInProgress.updateQueue = null; @@ -20441,7 +21098,12 @@ function resetWorkInProgress(workInProgress, renderLanes) { // Reset to the cloned values that createWorkInProgress would've. workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; - workInProgress.child = current.child; + workInProgress.child = current.child; // TODO: `subtreeFlags` should be reset to NoFlags, like we do in + // `createWorkInProgress`. Nothing reads this until the complete phase, + // currently, but it might in the future, and we should be consistent. + + workInProgress.subtreeFlags = current.subtreeFlags; + workInProgress.deletions = null; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. @@ -20468,13 +21130,33 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag) { +function createHostRootFiber(tag, strictModeLevelOverride) { var mode; if (tag === ConcurrentRoot) { - mode = ConcurrentMode | BlockingMode | StrictMode; + mode = ConcurrentMode | BlockingMode; + + if (strictModeLevelOverride !== null) { + if (strictModeLevelOverride >= 1) { + mode |= StrictLegacyMode; + } + } else { + { + mode |= StrictLegacyMode; + } + } } else if (tag === BlockingRoot) { - mode = BlockingMode | StrictMode; + mode = BlockingMode; + + if (strictModeLevelOverride !== null) { + if (strictModeLevelOverride >= 1) { + mode |= StrictLegacyMode; + } + } else { + { + mode |= StrictLegacyMode; + } + } } else { mode = NoMode; } @@ -20525,8 +21207,16 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: - fiberTag = Mode; - mode |= StrictMode; + fiberTag = Mode; // Legacy strict mode ( without any level prop) defaults to level 1. + + var level = + pendingProps.unstable_level == null ? 1 : pendingProps.unstable_level; // Levels cascade; higher levels inherit all lower level modes. + // It is explicitly not supported to lower a mode with nesting, only to increase it. + + if (level >= 1) { + mode |= StrictLegacyMode; + } + break; case REACT_PROFILER_TYPE: @@ -20548,6 +21238,10 @@ function createFiberFromTypeAndProps( // eslint-disable-next-line no-fallthrough + case REACT_CACHE_TYPE: + + // eslint-disable-next-line no-fallthrough + default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -20776,9 +21470,8 @@ function assignFiberPropertiesInDEV(target, source) { target.dependencies = source.dependencies; target.mode = source.mode; target.flags = source.flags; - target.nextEffect = source.nextEffect; - target.firstEffect = source.firstEffect; - target.lastEffect = source.lastEffect; + target.subtreeFlags = source.subtreeFlags; + target.deletions = source.deletions; target.lanes = source.lanes; target.childLanes = source.childLanes; target.alternate = source.alternate; @@ -20845,13 +21538,27 @@ function FiberRootNode(containerInfo, tag, hydrate) { } } -function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { +function createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride +) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag); + var uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + + { + var _initialState = { + element: null + }; + uninitializedFiber.memoizedState = _initialState; + } + initializeUpdateQueue(uninitializedFiber); return root; } @@ -20925,7 +21632,7 @@ function findHostInstanceWithWarning(component, methodName) { return null; } - if (hostFiber.mode & StrictMode) { + if (hostFiber.mode & StrictLegacyMode) { var componentName = getComponentName(fiber.type) || "Component"; if (!didWarnAboutFindNodeInStrictMode[componentName]) { @@ -20935,7 +21642,7 @@ function findHostInstanceWithWarning(component, methodName) { try { setCurrentFiber(hostFiber); - if (fiber.mode & StrictMode) { + if (fiber.mode & StrictLegacyMode) { error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + @@ -20974,8 +21681,20 @@ function findHostInstanceWithWarning(component, methodName) { } } -function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); +function createContainer( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride +) { + return createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride + ); } function updateContainer(element, container, parentComponent, callback) { { @@ -21039,7 +21758,12 @@ function updateContainer(element, container, parentComponent, callback) { } enqueueUpdate(current$1, update); - scheduleUpdateOnFiber(current$1, lane, eventTime); + var root = scheduleUpdateOnFiber(current$1, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, current$1, lane); + } + return lane; } function getPublicRootInstance(container) { @@ -21579,13 +22303,15 @@ function findHostInstance_DEPRECATED(componentOrHandle) { if (componentOrHandle == null) { return null; - } + } // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN if (componentOrHandle._nativeTag) { + // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN return componentOrHandle; - } + } // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) { + // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN return componentOrHandle.canonical; } @@ -21727,11 +22453,12 @@ function render(element, containerTag, callback) { if (!root) { // TODO (bvaughn): If we decide to keep the wrapper component, // We could create a wrapper for containerTag as well to reduce special casing. - root = createContainer(containerTag, LegacyRoot, false); + root = createContainer(containerTag, LegacyRoot, false, null, null); roots.set(containerTag, root); } - updateContainer(element, root, null, callback); + updateContainer(element, root, null, callback); // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN + return getPublicRootInstance(root); } @@ -21776,8 +22503,8 @@ exports.createPortal = createPortal$1; exports.dispatchCommand = dispatchCommand; exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; exports.findNodeHandle = findNodeHandle; -exports.sendAccessibilityEvent = sendAccessibilityEvent; exports.render = render; +exports.sendAccessibilityEvent = sendAccessibilityEvent; exports.stopSurface = stopSurface; exports.unmountComponentAtNode = unmountComponentAtNode; diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 035c6c10c7b3e8..dc0d1975d80703 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -919,7 +919,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_219 = { +var injectedNamesToPlugins$jscomp$inline_210 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -954,34 +954,34 @@ var injectedNamesToPlugins$jscomp$inline_219 = { } } }, - isOrderingDirty$jscomp$inline_220 = !1, - pluginName$jscomp$inline_221; -for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) + isOrderingDirty$jscomp$inline_211 = !1, + pluginName$jscomp$inline_212; +for (pluginName$jscomp$inline_212 in injectedNamesToPlugins$jscomp$inline_210) if ( - injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( - pluginName$jscomp$inline_221 + injectedNamesToPlugins$jscomp$inline_210.hasOwnProperty( + pluginName$jscomp$inline_212 ) ) { - var pluginModule$jscomp$inline_222 = - injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; + var pluginModule$jscomp$inline_213 = + injectedNamesToPlugins$jscomp$inline_210[pluginName$jscomp$inline_212]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || - namesToPlugins[pluginName$jscomp$inline_221] !== - pluginModule$jscomp$inline_222 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_212) || + namesToPlugins[pluginName$jscomp$inline_212] !== + pluginModule$jscomp$inline_213 ) { - if (namesToPlugins[pluginName$jscomp$inline_221]) + if (namesToPlugins[pluginName$jscomp$inline_212]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_221 + + pluginName$jscomp$inline_212 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_221 - ] = pluginModule$jscomp$inline_222; - isOrderingDirty$jscomp$inline_220 = !0; + pluginName$jscomp$inline_212 + ] = pluginModule$jscomp$inline_213; + isOrderingDirty$jscomp$inline_211 = !0; } } -isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_211 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -996,7 +996,11 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - null !== to + (from || to).stateNode.canonical._internalInstanceHandle + ? (from && + nativeFabricUIManager.setIsJSResponder(from.stateNode.node, !1), + to && nativeFabricUIManager.setIsJSResponder(to.stateNode.node, !0)) + : null !== to ? ReactNativePrivateInterface.UIManager.setJSResponder( to.stateNode.canonical._nativeTag, blockNativeResponder @@ -1020,7 +1024,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1039,6 +1044,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1065,6 +1071,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1098,7 +1106,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1186,19 +1194,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1525,6 +1528,328 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs = Scheduler_now(), + now = + 1e4 > initialTimeMs + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } +} +var nextTransitionLane = 512, + nextRetryLane = 8388608, + return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return (return_highestLanePriority = 15), 1; + case 2: + return (return_highestLanePriority = 14), 2; + case 4: + return (return_highestLanePriority = 13), 4; + case 8: + return (return_highestLanePriority = 12), 8; + case 16: + return (return_highestLanePriority = 11), 16; + case 32: + return (return_highestLanePriority = 10), 32; + case 64: + return (return_highestLanePriority = 9), 64; + case 128: + return (return_highestLanePriority = 8), 128; + case 256: + return (return_highestLanePriority = 7), 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: + return (return_highestLanePriority = 6), lanes & 8388096; + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return (return_highestLanePriority = 5), lanes & 125829120; + case 134217728: + return (return_highestLanePriority = 4), 134217728; + case 268435456: + return (return_highestLanePriority = 3), 268435456; + case 536870912: + return (return_highestLanePriority = 2), 536870912; + case 1073741824: + return (return_highestLanePriority = 1), 1073741824; + default: + return (return_highestLanePriority = 8), lanes; + } +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + 0 !== expiredLanes + ? ((nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15)) + : ((expiredLanes = pendingLanes & 268435455), + 0 !== expiredLanes + ? ((pendingLanes = expiredLanes & ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))) + : ((pendingLanes &= ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + suspendedLanes = return_highestLanePriority; + if ( + nextLanePriority <= suspendedLanes || + (8 === nextLanePriority && 6 === suspendedLanes) + ) + return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (nextLanePriority = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << nextLanePriority), + (nextLanes |= root[nextLanePriority]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return 8; + case 10: + return 32; + case 8: + return 128; + case 2: + return 536870912; + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$7 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$7; + remainingLanes[index$7] = 0; + eventTimes[index$7] = -1; + root[index$7] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$8 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$8; + (lane & entangledLanes) | (root[index$8] & entangledLanes) && + (root[index$8] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_now$1 = Scheduler.unstable_now; +Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." @@ -1740,296 +2065,17 @@ function invalidateContextProvider(workInProgress, type, didChange) { push(didPerformWorkStackCursor, didChange); } var rendererID = null, - injectedHook = null, - Scheduler_now = Scheduler.unstable_now; -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, - fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; + injectedHook = null; +function onCommitRoot(root) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } + injectedHook.onCommitFiberRoot( + rendererID, + root, + void 0, + 128 === (root.current.flags & 128) + ); + } catch (err) {} } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2097,10 +2143,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue2 = currentValue; + context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2151,13 +2197,14 @@ function readContext(context, observedBits) { } return context._currentValue2; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2183,14 +2230,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2259,111 +2324,110 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2419,7 +2483,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2430,7 +2495,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2440,7 +2506,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2588,24 +2655,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw Error( + throw ((returnFiber = Object.prototype.toString.call(newChild)), + Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) + ("[object Object]" === returnFiber ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : returnFiber) + "). If you meant to render a collection of children, use an array instead." - ); + )); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2637,16 +2702,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2661,7 +2726,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2775,15 +2849,7 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2816,17 +2882,9 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (existingChildren = existingChildren.get( - null === newChild.key ? newIdx : newChild.key - ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + null === newChild.key ? newIdx : newChild.key + ) || null), + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3032,43 +3090,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + isObject = newChild.type; + if (isObject === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3246,7 +3299,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3398,10 +3451,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3426,22 +3480,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3481,7 +3546,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3511,25 +3576,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$11 = 31 - clz32(lanes), - lane = 1 << index$11; - entanglements[index$11] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3556,6 +3609,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3581,6 +3636,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3629,7 +3686,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3637,10 +3694,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(132096, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3725,33 +3782,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 8388096) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3808,6 +3887,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3983,7 +4064,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4059,14 +4140,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4083,30 +4165,39 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 2)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, current), - null - ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= nextProps; + } else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4116,7 +4207,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4141,7 +4232,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4316,7 +4407,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4324,7 +4415,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4338,7 +4429,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4359,7 +4450,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4403,18 +4494,21 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; +} function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4431,7 +4525,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4443,9 +4539,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), + (workInProgress.lanes = 8388608), current ); renderLanes = createFiberFromOffscreen( @@ -4471,8 +4569,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4499,8 +4600,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4523,7 +4627,7 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren)) : (progressedPrimaryFragment = createFiberFromOffscreen( @@ -4556,13 +4660,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4572,26 +4677,22 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + 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), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4616,8 +4717,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4627,16 +4727,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4645,9 +4743,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4670,7 +4768,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4691,8 +4789,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4714,19 +4811,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4736,25 +4825,33 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } - return null; + return workInProgress.child; +} +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 & 6454) || 0 !== (current.subtreeFlags & 6454)) + return !1; + current = current.sibling; + } + return !0; } var appendAllChildren, updateHostContainer, @@ -4871,21 +4968,24 @@ function appendAllChildrenToContainer( node = node.sibling; } } -updateHostContainer = function(workInProgress) { +updateHostContainer = function(current, workInProgress) { var portalOrRoot = workInProgress.stateNode; - if (null !== workInProgress.firstEffect) { - var container = portalOrRoot.containerInfo, - newChildSet = createChildNodeSet(container); + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); portalOrRoot.pendingChildren = newChildSet; workInProgress.flags |= 4; - completeRoot(container, newChildSet); + completeRoot(current, newChildSet); } }; updateHostComponent$1 = function(current, workInProgress, type, newProps) { type = current.stateNode; var oldProps = current.memoizedProps; - if ((current = null === workInProgress.firstEffect) && oldProps === newProps) + if ( + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps + ) workInProgress.stateNode = type; else { var recyclableInstance = workInProgress.stateNode; @@ -4903,15 +5003,15 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { current && null === updatePayload ? (workInProgress.stateNode = type) : ((newProps = updatePayload), - (recyclableInstance = type.node), + (oldProps = type.node), (type = { node: current ? null !== newProps - ? cloneNodeWithNewProps(recyclableInstance, newProps) - : cloneNode(recyclableInstance) + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4947,16 +5047,40 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$64 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), + for (var lastTailNode$62 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$62 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$64 + null === lastTailNode$62 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$64.sibling = null); + : (lastTailNode$62.sibling = null); } } +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$63 = completedWork.child; null !== child$63; ) + (newChildLanes |= child$63.lanes | child$63.childLanes), + (subtreeFlags |= child$63.subtreeFlags & 131072), + (subtreeFlags |= child$63.flags & 131072), + (child$63.return = completedWork), + (child$63 = child$63.sibling); + else + for (child$63 = completedWork.child; null !== child$63; ) + (newChildLanes |= child$63.lanes | child$63.childLanes), + (subtreeFlags |= child$63.subtreeFlags), + (subtreeFlags |= child$63.flags), + (child$63.return = completedWork), + (child$63 = child$63.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4970,76 +5094,81 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); 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; - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); - rootContainerInstance = createNode( + renderLanes = createNode( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderLanes, + type, newProps, workInProgress ); - current = { node: rootContainerInstance, canonical: current }; + current = { node: renderLanes, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 128); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5055,25 +5184,25 @@ function completeWork(current, workInProgress, renderLanes) { "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); - rootContainerInstance = requiredContext(contextStackCursor$1.current); + renderLanes = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - rootContainerInstance, + renderLanes, workInProgress ); } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5088,82 +5217,92 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } newProps && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderLanes = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), + (renderLanes = newProps), + (type = current), + (renderLanes.flags &= 131074), + (updatePayload = renderLanes.alternate), null === updatePayload - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = renderLanes), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null)) - : ((rootContainerInstance.childLanes = - updatePayload.childLanes), - (rootContainerInstance.lanes = updatePayload.lanes), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = + ? ((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 = updatePayload.subtreeFlags), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = + (renderLanes.memoizedState = updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (rootContainerInstance.type = updatePayload.type), - (renderLanes = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderLanes + (renderLanes.updateQueue = updatePayload.updateQueue), + (renderLanes.type = updatePayload.type), + (type = updatePayload.dependencies), + (renderLanes.dependencies = + null === type ? null : { - lanes: renderLanes.lanes, - firstContext: renderLanes.firstContext + lanes: type.lanes, + firstContext: type.firstContext })), (newProps = newProps.sibling); push( @@ -5174,78 +5313,74 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + 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) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 2)) || + bubbleProperties(workInProgress), null ); } @@ -5260,8 +5395,8 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null; case 3: popHostContainer(); @@ -5269,11 +5404,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5281,8 +5416,8 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null ); case 19: @@ -5290,10 +5425,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5372,152 +5509,161 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + 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." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - 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." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$81 = finishedRoot.create; - finishedRoot.destroy = create$81(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$81 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$81; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$81 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$81, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode.canonical; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$80 = effect.create; + effect.destroy = create$80(); } - return; - case 5: - null === current && finishedWork.flags & 4 && shim(); - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - 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 detachFiberMutation(fiber) { +function detachFiberAfterEffects(fiber) { fiber.alternate = null; fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function commitWork(current, finishedWork) { @@ -5526,19 +5672,7 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedWork = current = current.next; - do { - if (3 === (finishedWork.tag & 3)) { - var destroy = finishedWork.destroy; - finishedWork.destroy = void 0; - void 0 !== destroy && destroy(); - } - finishedWork = finishedWork.next; - } while (finishedWork !== current); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 12: return; @@ -5559,7 +5693,6 @@ function commitWork(current, finishedWork) { case 1: case 5: case 6: - case 20: break a; case 3: case 4: @@ -5570,28 +5703,276 @@ function commitWork(current, finishedWork) { ); } } -function attachSuspenseRetryListeners(finishedWork) { - var wakeables = finishedWork.updateQueue; - if (null !== wakeables) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - wakeables.forEach(function(wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - retryCache.has(wakeable) || - (retryCache.add(wakeable), wakeable.then(retry, retry)); - }); +function attachSuspenseRetryListeners(finishedWork) { + var wakeables = finishedWork.updateQueue; + if (null !== wakeables) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + null === retryCache && + (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); + wakeables.forEach(function(wakeable) { + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + retryCache.has(wakeable) || + (retryCache.add(wakeable), wakeable.then(retry, retry)); + }); + } +} +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + renderPriorityLevel = root.deletions; + if (null !== renderPriorityLevel) + for ( + firstChild = 0; + firstChild < renderPriorityLevel.length; + firstChild++ + ) { + var childToDelete = renderPriorityLevel[firstChild]; + 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; + if (void 0 !== destroy && 0 !== (tag & 2)) { + _effect = current; + var nearestMountedAncestor = root; + try { + destroy(); + } catch (error) { + captureCommitPhaseError( + _effect, + nearestMountedAncestor, + error + ); + } + } + 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 (unmountError) { + captureCommitPhaseError(current, root, unmountError); + } + 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; + childToDelete.return = null; + null !== alternate && (alternate.return = null); + } catch (error) { + captureCommitPhaseError(childToDelete, root, error); + } + } + renderPriorityLevel = root.child; + if (0 !== (root.subtreeFlags & 6454) && null !== renderPriorityLevel) + (renderPriorityLevel.return = root), (nextEffect = renderPriorityLevel); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var flags = root.flags; + if (flags & 256) { + 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)); + } + } + switch (flags & 2054) { + case 2: + root.flags &= -3; + break; + case 6: + root.flags &= -3; + commitWork(root.alternate, root); + break; + case 2048: + root.flags &= -2049; + break; + case 2052: + root.flags &= -2049; + commitWork(root.alternate, root); + break; + case 4: + commitWork(root.alternate, root); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + renderPriorityLevel = root.sibling; + if (null !== renderPriorityLevel) { + renderPriorityLevel.return = root.return; + nextEffect = renderPriorityLevel; + break; + } + nextEffect = root.return; + } + } +} +function commitLayoutEffects(finishedWork) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; + try { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, firstChild); + break; + case 1: + var instance = firstChild.stateNode; + if (firstChild.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + firstChild.elementType === firstChild.type + ? current.memoizedProps + : resolveDefaultProps( + firstChild.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = firstChild.updateQueue; + null !== updateQueue && + commitUpdateQueue(firstChild, updateQueue, instance); + break; + case 3: + var updateQueue$81 = firstChild.updateQueue; + if (null !== updateQueue$81) { + current = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { + case 5: + current = firstChild.child.stateNode.canonical; + break; + case 1: + current = firstChild.child.stateNode; + } + commitUpdateQueue(firstChild, updateQueue$81, current); + } + break; + case 5: + null === current && firstChild.flags & 4 && shim(); + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + 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." + ); + } + if (firstChild.flags & 256) { + current = void 0; + var ref = firstChild.ref; + if (null !== ref) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { + case 5: + current = instance$jscomp$0.canonical; + break; + default: + current = instance$jscomp$0; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + } + if (firstChild === fiber) { + nextEffect = null; + break; + } + current = firstChild.sibling; + if (null !== current) { + current.return = firstChild.return; + nextEffect = current; + break; + } + nextEffect = firstChild.return; + } } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; -} var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, @@ -5603,30 +5984,22 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -5636,30 +6009,22 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } + if (0 === (fiber & 1)) return 1; + if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) + ? (fiber = findUpdateLane(12)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); + (fiber = findUpdateLane(fiber))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -5690,7 +6055,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime)); - mostRecentlyUpdatedRoot = fiber; + return fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -5738,45 +6103,42 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && + 0 === suspendedLanes + ? (null !== existingCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); - } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); - root.callbackPriority = currentTime; - root.callbackNode = existingCallbackNode; - } -} -function performConcurrentWorkOnRoot(root) { + (root.callbackPriority = 0)) + : root.callbackPriority !== currentTime && + (null != existingCallbackNode && + Scheduler_cancelCallback(existingCallbackNode), + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = null)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority( + currentTime + )), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))), + (root.callbackPriority = currentTime), + (root.callbackNode = existingCallbackNode)); +} +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; + currentEventTransitionLane = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -5787,16 +6149,22 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - var exitStatus = lanes; + if (didTimeout) + return ( + (root.expiredLanes |= lanes & root.pendingLanes), + ensureRootIsScheduled(root, now()), + null + ); + didTimeout = lanes; var prevExecutionContext = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( workInProgressRoot !== root || - workInProgressRootRenderLanes !== exitStatus + workInProgressRootRenderLanes !== didTimeout ) (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, exitStatus); + prepareFreshStack(root, didTimeout); do try { workLoopConcurrent(); @@ -5809,19 +6177,17 @@ function performConcurrentWorkOnRoot(root) { ReactCurrentDispatcher$2.current = prevDispatcher; executionContext = prevExecutionContext; null !== workInProgress - ? (exitStatus = 0) + ? (didTimeout = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && + (didTimeout = workInProgressRootExitStatus)); + if (0 !== didTimeout) { + 2 === didTimeout && ((executionContext |= 64), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -5829,7 +6195,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -5839,9 +6205,9 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 125829120) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; prevExecutionContext = root.suspendedLanes; @@ -5852,7 +6218,7 @@ function performConcurrentWorkOnRoot(root) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -5860,12 +6226,12 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; + if ((lanes & 8388096) === lanes) break; + didTimeout = root.eventTimes; for (prevExecutionContext = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); prevDispatcher = 1 << index$4; - index$4 = exitStatus[index$4]; + index$4 = didTimeout[index$4]; index$4 > prevExecutionContext && (prevExecutionContext = index$4); lanes &= ~prevDispatcher; } @@ -5912,9 +6278,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$9 = 31 - clz32(suspendedLanes), - lane = 1 << index$9; - root[index$9] = -1; + var index$6 = 31 - clz32(suspendedLanes), + lane = 1 << index$6; + root[index$6] = -1; suspendedLanes &= ~lane; } } @@ -5922,17 +6288,12 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( + var lanes = root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); + ? workInProgressRootRenderLanes + : getNextLanes(root, 0); + var exitStatus = renderRootSync(root, lanes); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -5951,11 +6312,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -5995,7 +6351,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6005,10 +6361,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6044,15 +6419,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6063,15 +6441,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$76 = returnFiber; + workInProgress$75 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$76.tag)) { - var nextState = workInProgress$76.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$75.tag)) { + var nextState = workInProgress$75.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$76.memoizedProps; + var props = workInProgress$75.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6083,16 +6461,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$76.updateQueue; + var wakeables = workInProgress$75.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$76.updateQueue = updateQueue; + workInProgress$75.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$76.mode & 2)) { - workInProgress$76.flags |= 64; - sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + if ( + 0 === (workInProgress$75.mode & 1) && + workInProgress$75 !== returnFiber + ) { + workInProgress$75.flags |= 128; + sourceFiber.flags |= 65536; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6123,12 +6504,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$76.flags |= 8192; - workInProgress$76.lanes = thrownValue; + workInProgress$75.flags |= 16384; + workInProgress$75.lanes = thrownValue; break a; } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$75 = workInProgress$75.return; + } while (null !== workInProgress$75); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6137,47 +6518,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$76 = returnFiber; + workInProgress$75 = returnFiber; do { - switch (workInProgress$76.tag) { + switch (workInProgress$75.tag) { case 3: root = value; - workInProgress$76.flags |= 8192; + workInProgress$75.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$77 = createRootErrorUpdate( - workInProgress$76, + workInProgress$75.lanes |= thrownValue; + var update$76 = createRootErrorUpdate( + workInProgress$75, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$77); + enqueueCapturedUpdate(workInProgress$75, update$76); break a; case 1: root = value; - var ctor = workInProgress$76.type, - instance = workInProgress$76.stateNode; + var ctor = workInProgress$75.type, + instance = workInProgress$75.stateNode; if ( - 0 === (workInProgress$76.flags & 64) && + 0 === (workInProgress$75.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$76.flags |= 8192; + workInProgress$75.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$80 = createClassErrorUpdate( - workInProgress$76, + workInProgress$75.lanes |= thrownValue; + var update$79 = createClassErrorUpdate( + workInProgress$75, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$80); + enqueueCapturedUpdate(workInProgress$75, update$79); break a; } } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$75 = workInProgress$75.return; + } while (null !== workInProgress$75); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6238,47 +6619,25 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - current = completeWork(current, completedWork, subtreeRenderLanes); - if (null !== current) { - workInProgress = current; - return; - } - current = completedWork; + if (0 === (completedWork.flags & 8192)) { if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) + ((current = completeWork(current, completedWork, subtreeRenderLanes)), + null !== current) ) { - for (var newChildLanes = 0, child = current.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (child = child.sibling); - current.childLanes = newChildLanes; + workInProgress = current; + return; } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6299,7 +6658,8 @@ function commitRootImpl(root, renderPriorityLevel) { while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 48)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork; + var finishedWork = root.finishedWork, + lanes = root.finishedLanes; if (null === finishedWork) return null; root.finishedWork = null; root.finishedLanes = 0; @@ -6308,252 +6668,48 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$10 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$10; - remainingLanes$jscomp$0[index$10] = 0; - eventTimes[index$10] = -1; - expirationTimes[index$10] = -1; - noLongerPendingLanes &= ~lane; - } + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && + 0 === (remainingLanes & 8) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; - executionContext |= 32; - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; - nextEffect = remainingLanes; - do - try { - for (; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - nextEffect.flags &= -3; - break; - case 6: - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - eventTimes = nextEffect; - a: for (noLongerPendingLanes = expirationTimes = eventTimes; ; ) { - index$10 = noLongerPendingLanes; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, index$10); - } catch (err) {} - switch (index$10.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = index$10.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next; - lane = firstEffect; - do { - var _effect2 = lane, - destroy = _effect2.destroy, - tag = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (tag & 4)) - enqueuePendingPassiveHookEffectUnmount( - index$10, - lane - ); - else { - _effect2 = index$10; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } - } - lane = lane.next; - } while (lane !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(index$10); - var instance = index$10.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (lane = index$10), - (_effect2 = instance), - (_effect2.props = lane.memoizedProps), - (_effect2.state = lane.memoizedState), - _effect2.componentWillUnmount(); - } catch (unmountError) { - captureCommitPhaseError(index$10, unmountError); - } - break; - case 5: - safelyDetachRef(index$10); - break; - case 4: - createChildNodeSet(index$10.stateNode.containerInfo); - } - if (null !== noLongerPendingLanes.child) - (noLongerPendingLanes.child.return = noLongerPendingLanes), - (noLongerPendingLanes = noLongerPendingLanes.child); - else { - if (noLongerPendingLanes === expirationTimes) break; - for (; null === noLongerPendingLanes.sibling; ) { - if ( - null === noLongerPendingLanes.return || - noLongerPendingLanes.return === expirationTimes - ) - break a; - noLongerPendingLanes = noLongerPendingLanes.return; - } - noLongerPendingLanes.sibling.return = - noLongerPendingLanes.return; - noLongerPendingLanes = noLongerPendingLanes.sibling; - } - } - var alternate = eventTimes.alternate; - detachFiberMutation(eventTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$87) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$87); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance$jscomp$0.canonical; - break; - default: - current = instance$jscomp$0; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$88) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$88); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; - requestPaint(); - executionContext = remainingLanes$jscomp$0; - } else root.current = finishedWork; - if (rootDoesHavePassiveEffects) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (renderPriorityLevel = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((flags$jscomp$0 = nextEffect), - (flags$jscomp$0.sibling = null), - (flags$jscomp$0.stateNode = null)), - (nextEffect = renderPriorityLevel); + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + 0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes + ? ((remainingLanes = executionContext), + (executionContext |= 32), + (ReactCurrentOwner$2.current = null), + commitBeforeMutationEffects(root, finishedWork), + commitMutationEffects(root, renderPriorityLevel, finishedWork), + (root.current = finishedWork), + commitLayoutEffects(finishedWork, root, lanes), + requestPaint(), + (executionContext = remainingLanes)) + : (root.current = finishedWork); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsRenderPriority = renderPriorityLevel)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - 1 === remainingLanes + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - void 0, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6564,30 +6720,6 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6599,24 +6731,6 @@ function flushPassiveEffects() { } return !1; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; @@ -6625,40 +6739,103 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$93 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$93.destroy; - effect$93.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); + for (nextEffect = root.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + if (fiber$jscomp$0 === fiberToDelete) { + nextEffect = null; + break; + } + child$jscomp$0 = fiber$jscomp$0.sibling; + if (null !== child$jscomp$0) { + child$jscomp$0.return = fiber$jscomp$0.return; + nextEffect = child$jscomp$0; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } + fiber$jscomp$0 = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); + null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); + } + nextEffect = fiber; } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$93 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; - try { - var create$97 = effect$93.create; - effect$93.destroy = create$97(); - } catch (error$98) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$98); } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + a: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + child = fiber.sibling; + if (null !== child) { + child.return = fiber.return; + nextEffect = child; + break a; + } + nextEffect = fiber.return; + } } - for (create$97 = root.current.firstEffect; null !== create$97; ) - (root = create$97.nextEffect), - (create$97.nextEffect = null), - create$97.flags & 8 && - ((create$97.sibling = null), (create$97.stateNode = null)), - (create$97 = root); + for (nextEffect = root = root.current; null !== nextEffect; ) + if ( + ((fiber = nextEffect), + (child = fiber.child), + 0 !== (fiber.subtreeFlags & 1040) && null !== child) + ) + (child.return = fiber), (nextEffect = child); + else + a: for (fiber = root; null !== nextEffect; ) { + child = nextEffect; + if (0 !== (child.flags & 1024)) + try { + switch (child.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, child); + } + } catch (error) { + captureCommitPhaseError(child, child.return, error); + } + if (child === fiber) { + nextEffect = null; + break a; + } + deletions = child.sibling; + if (null !== deletions) { + deletions.return = child.return; + nextEffect = deletions; + break a; + } + nextEffect = child.return; + } executionContext = prevExecutionContext; flushSyncCallbackQueue(); return !0; @@ -6673,42 +6850,50 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { (markRootUpdated(rootFiber, 1, sourceFiber), ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6720,7 +6905,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 125829120) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6733,14 +6918,13 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + 0 === (wakeable & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) + : 0 === (wakeable & 2) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6756,78 +6940,83 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateLanes; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, + if (0 === (renderLanes & updateLanes)) { + didReceiveUpdate = !1; + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer( workInProgress, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + break; + case 10: + updateLanes = workInProgress.type._context; + var nextValue = workInProgress.memoizedProps.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = nextValue; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); + return null !== workInProgress ? workInProgress.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; + case 19: + updateLanes = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; + } + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); + } + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -6839,22 +7028,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -6864,8 +7053,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -6876,9 +7065,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -6890,28 +7079,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6920,7 +7109,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6929,7 +7118,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6938,8 +7127,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -6947,7 +7136,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -6955,32 +7144,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -6991,19 +7180,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7043,16 +7231,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7089,27 +7277,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; + nextValue = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue2); - context$jscomp$0._currentValue2 = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = nextValue.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = hasContext; + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = objectIs(oldValue, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits(oldValue, hasContext) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7121,15 +7303,14 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + oldValue = workInProgress.child, + null !== oldValue && (oldValue.return = workInProgress); + null !== oldValue; ) { - var list = context$jscomp$0.dependencies; + var list = oldValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + getDerivedStateFromProps = oldValue.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7139,20 +7320,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (1 === oldValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + oldValue.lanes |= renderLanes; + dependency = oldValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(oldValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7160,16 +7345,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + 10 === oldValue.tag + ? oldValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; + : oldValue.child + : oldValue.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + getDerivedStateFromProps.return = oldValue; else for ( - getDerivedStateFromProps = context$jscomp$0; + getDerivedStateFromProps = oldValue; null !== getDerivedStateFromProps; ) { @@ -7177,20 +7362,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + oldValue = getDerivedStateFromProps.sibling; + if (null !== oldValue) { + oldValue.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = oldValue; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - context$jscomp$0 = getDerivedStateFromProps; + oldValue = getDerivedStateFromProps; } + } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7198,28 +7384,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7237,11 +7423,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7251,8 +7437,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7284,8 +7470,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; } @@ -7323,9 +7509,9 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null)); + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null)); + workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7360,15 +7546,18 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 8; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + 1 <= + (null == pendingProps.unstable_level + ? 1 + : pendingProps.unstable_level) && (mode |= 16); break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 4)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -7555,7 +7744,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7587,10 +7777,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_865 = { + devToolsConfig$jscomp$inline_914 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7605,11 +7795,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1054 = { - bundleType: devToolsConfig$jscomp$inline_865.bundleType, - version: devToolsConfig$jscomp$inline_865.version, - rendererPackageName: devToolsConfig$jscomp$inline_865.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_865.rendererConfig, +var internals$jscomp$inline_1178 = { + bundleType: devToolsConfig$jscomp$inline_914.bundleType, + version: devToolsConfig$jscomp$inline_914.version, + rendererPackageName: devToolsConfig$jscomp$inline_914.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_914.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7624,7 +7814,7 @@ var internals$jscomp$inline_1054 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_865.findFiberByHostInstance || + devToolsConfig$jscomp$inline_914.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -7633,16 +7823,16 @@ var internals$jscomp$inline_1054 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1055 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1179 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1055.isDisabled && - hook$jscomp$inline_1055.supportsFiber + !hook$jscomp$inline_1179.isDisabled && + hook$jscomp$inline_1179.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1055.inject( - internals$jscomp$inline_1054 + (rendererID = hook$jscomp$inline_1179.inject( + internals$jscomp$inline_1178 )), - (injectedHook = hook$jscomp$inline_1055); + (injectedHook = hook$jscomp$inline_1179); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -7684,10 +7874,11 @@ exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = createFiber(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); + var JSCompiler_inline_result = createFiber(3, null, null, 0); + root.current = JSCompiler_inline_result; + JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; + initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 51f399468cdf57..96243f376c9204 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -920,7 +920,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_223 = { +var injectedNamesToPlugins$jscomp$inline_216 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -955,34 +955,34 @@ 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_217 = !1, + pluginName$jscomp$inline_218; +for (pluginName$jscomp$inline_218 in injectedNamesToPlugins$jscomp$inline_216) if ( - injectedNamesToPlugins$jscomp$inline_223.hasOwnProperty( - pluginName$jscomp$inline_225 + injectedNamesToPlugins$jscomp$inline_216.hasOwnProperty( + pluginName$jscomp$inline_218 ) ) { - var pluginModule$jscomp$inline_226 = - injectedNamesToPlugins$jscomp$inline_223[pluginName$jscomp$inline_225]; + var pluginModule$jscomp$inline_219 = + injectedNamesToPlugins$jscomp$inline_216[pluginName$jscomp$inline_218]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_225) || - namesToPlugins[pluginName$jscomp$inline_225] !== - pluginModule$jscomp$inline_226 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_218) || + namesToPlugins[pluginName$jscomp$inline_218] !== + pluginModule$jscomp$inline_219 ) { - if (namesToPlugins[pluginName$jscomp$inline_225]) + if (namesToPlugins[pluginName$jscomp$inline_218]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_225 + + pluginName$jscomp$inline_218 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_225 - ] = pluginModule$jscomp$inline_226; - isOrderingDirty$jscomp$inline_224 = !0; + pluginName$jscomp$inline_218 + ] = pluginModule$jscomp$inline_219; + isOrderingDirty$jscomp$inline_217 = !0; } } -isOrderingDirty$jscomp$inline_224 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_217 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -997,7 +997,11 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - null !== to + (from || to).stateNode.canonical._internalInstanceHandle + ? (from && + nativeFabricUIManager.setIsJSResponder(from.stateNode.node, !1), + to && nativeFabricUIManager.setIsJSResponder(to.stateNode.node, !0)) + : null !== to ? ReactNativePrivateInterface.UIManager.setJSResponder( to.stateNode.canonical._nativeTag, blockNativeResponder @@ -1021,7 +1025,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1040,6 +1045,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1066,6 +1072,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1099,7 +1107,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1187,19 +1195,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1526,6 +1529,342 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +var requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs = Scheduler_now(), + now = + 1e4 > initialTimeMs + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } +} +var nextTransitionLane = 512, + nextRetryLane = 8388608, + return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return (return_highestLanePriority = 15), 1; + case 2: + return (return_highestLanePriority = 14), 2; + case 4: + return (return_highestLanePriority = 13), 4; + case 8: + return (return_highestLanePriority = 12), 8; + case 16: + return (return_highestLanePriority = 11), 16; + case 32: + return (return_highestLanePriority = 10), 32; + case 64: + return (return_highestLanePriority = 9), 64; + case 128: + return (return_highestLanePriority = 8), 128; + case 256: + return (return_highestLanePriority = 7), 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: + return (return_highestLanePriority = 6), lanes & 8388096; + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return (return_highestLanePriority = 5), lanes & 125829120; + case 134217728: + return (return_highestLanePriority = 4), 134217728; + case 268435456: + return (return_highestLanePriority = 3), 268435456; + case 536870912: + return (return_highestLanePriority = 2), 536870912; + case 1073741824: + return (return_highestLanePriority = 1), 1073741824; + default: + return (return_highestLanePriority = 8), lanes; + } +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + 0 !== expiredLanes + ? ((nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15)) + : ((expiredLanes = pendingLanes & 268435455), + 0 !== expiredLanes + ? ((pendingLanes = expiredLanes & ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))) + : ((pendingLanes &= ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + suspendedLanes = return_highestLanePriority; + if ( + nextLanePriority <= suspendedLanes || + (8 === nextLanePriority && 6 === suspendedLanes) + ) + return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (nextLanePriority = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << nextLanePriority), + (nextLanes |= root[nextLanePriority]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return 8; + case 10: + return 32; + case 8: + return 128; + case 2: + return 536870912; + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$7 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$7; + remainingLanes[index$7] = 0; + eventTimes[index$7] = -1; + root[index$7] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$8 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$8; + (lane & entangledLanes) | (root[index$8] & entangledLanes) && + (root[index$8] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_now$1 = Scheduler.unstable_now; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." @@ -1742,310 +2081,17 @@ function invalidateContextProvider(workInProgress, type, didChange) { } var rendererID = null, injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, - Scheduler_now = Scheduler.unstable_now; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function onCommitRoot(root, priorityLevel) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + 128 === (root.current.flags & 128) + ); + } catch (err) {} } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2113,10 +2159,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue2 = currentValue; + context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2167,13 +2213,14 @@ function readContext(context, observedBits) { } return context._currentValue2; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2199,14 +2246,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2275,111 +2340,110 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2435,7 +2499,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2446,7 +2511,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2456,7 +2522,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2604,24 +2671,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw Error( + throw ((returnFiber = Object.prototype.toString.call(newChild)), + Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) + ("[object Object]" === returnFiber ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : returnFiber) + "). If you meant to render a collection of children, use an array instead." - ); + )); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2653,16 +2718,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2677,7 +2742,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2789,17 +2863,9 @@ function ChildReconciler(shouldTrackSideEffects) { : updateTextNode(returnFiber, oldFiber, "" + newChild, lanes); if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + case REACT_ELEMENT_TYPE: + return newChild.key === key + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2834,15 +2900,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3048,43 +3106,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + isObject = newChild.type; + if (isObject === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3262,7 +3315,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3414,10 +3467,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3442,22 +3496,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3497,7 +3562,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3527,25 +3592,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$11 = 31 - clz32(lanes), - lane = 1 << index$11; - entanglements[index$11] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3572,6 +3625,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3597,6 +3652,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3645,7 +3702,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3653,10 +3710,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(132096, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3741,33 +3798,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 8388096) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3824,6 +3903,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4014,7 +4095,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4090,14 +4171,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4114,31 +4196,40 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 2)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + markSpawnedWork(1073741824), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - markSpawnedWork(1073741824), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, current), - null - ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= nextProps; + } else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4148,7 +4239,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4173,7 +4264,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4348,7 +4439,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4356,7 +4447,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4370,7 +4461,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4391,7 +4482,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4439,18 +4530,21 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; +} function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4467,7 +4561,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4479,10 +4575,12 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608), current ); renderLanes = createFiberFromOffscreen( @@ -4508,8 +4606,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4536,8 +4637,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4560,10 +4664,10 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 8 && + workInProgress.mode & 4 && ((progressedPrimaryFragment.actualDuration = 0), (progressedPrimaryFragment.actualStartTime = -1), (progressedPrimaryFragment.selfBaseDuration = 0), @@ -4598,13 +4702,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4614,33 +4719,27 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + 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 & 8 && + workInProgress.mode & 4 && ((primaryChildren.actualDuration = 0), (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration), - (primaryChildren.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration)), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (primaryChildren.selfBaseDuration = current.selfBaseDuration), + (primaryChildren.treeBaseDuration = current.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4665,8 +4764,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4676,16 +4774,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4694,9 +4790,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4719,7 +4815,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4740,8 +4836,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4763,19 +4858,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4786,25 +4873,33 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } - return null; + return workInProgress.child; +} +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 & 6454) || 0 !== (current.subtreeFlags & 6454)) + return !1; + current = current.sibling; + } + return !0; } var appendAllChildren, updateHostContainer, @@ -4921,21 +5016,24 @@ function appendAllChildrenToContainer( node = node.sibling; } } -updateHostContainer = function(workInProgress) { +updateHostContainer = function(current, workInProgress) { var portalOrRoot = workInProgress.stateNode; - if (null !== workInProgress.firstEffect) { - var container = portalOrRoot.containerInfo, - newChildSet = createChildNodeSet(container); + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); portalOrRoot.pendingChildren = newChildSet; workInProgress.flags |= 4; - completeRoot(container, newChildSet); + completeRoot(current, newChildSet); } }; updateHostComponent$1 = function(current, workInProgress, type, newProps) { type = current.stateNode; var oldProps = current.memoizedProps; - if ((current = null === workInProgress.firstEffect) && oldProps === newProps) + if ( + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps + ) workInProgress.stateNode = type; else { var recyclableInstance = workInProgress.stateNode; @@ -4953,15 +5051,15 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { current && null === updatePayload ? (workInProgress.stateNode = type) : ((newProps = updatePayload), - (recyclableInstance = type.node), + (oldProps = type.node), (type = { node: current ? null !== newProps - ? cloneNodeWithNewProps(recyclableInstance, newProps) - : cloneNode(recyclableInstance) + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4997,16 +5095,76 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$65 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$65 = lastTailNode), + for (var lastTailNode$63 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$65 + null === lastTailNode$63 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$65.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 & 4)) { + for ( + var treeBaseDuration$65 = completedWork.selfBaseDuration, + child$66 = completedWork.child; + null !== child$66; + + ) + (newChildLanes |= child$66.lanes | child$66.childLanes), + (subtreeFlags |= child$66.subtreeFlags & 131072), + (subtreeFlags |= child$66.flags & 131072), + (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 & 131072), + (subtreeFlags |= treeBaseDuration$65.flags & 131072), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + else if (0 !== (completedWork.mode & 4)) { + 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; switch (workInProgress.tag) { @@ -5020,76 +5178,81 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); 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; - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); - rootContainerInstance = createNode( + renderLanes = createNode( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderLanes, + type, newProps, workInProgress ); - current = { node: rootContainerInstance, canonical: current }; + current = { node: renderLanes, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 128); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5105,30 +5268,30 @@ function completeWork(current, workInProgress, renderLanes) { "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); - rootContainerInstance = requiredContext(contextStackCursor$1.current); + renderLanes = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - rootContainerInstance, + renderLanes, workInProgress ); } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return ( (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 8) && + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress ); newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5143,89 +5306,100 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } newProps && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 4) && + newProps && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), + (renderLanes = newProps), (updatePayload = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (renderLanes = rootContainerInstance.alternate), - null === renderLanes - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = updatePayload), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null), - (rootContainerInstance.selfBaseDuration = 0), - (rootContainerInstance.treeBaseDuration = 0)) - : ((rootContainerInstance.childLanes = - renderLanes.childLanes), - (rootContainerInstance.lanes = renderLanes.lanes), - (rootContainerInstance.child = renderLanes.child), - (rootContainerInstance.memoizedProps = - renderLanes.memoizedProps), - (rootContainerInstance.memoizedState = - renderLanes.memoizedState), - (rootContainerInstance.updateQueue = - renderLanes.updateQueue), - (rootContainerInstance.type = renderLanes.type), - (updatePayload = renderLanes.dependencies), - (rootContainerInstance.dependencies = + (renderLanes.flags &= 131074), + (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 = type.subtreeFlags), + (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 }), - (rootContainerInstance.selfBaseDuration = - renderLanes.selfBaseDuration), - (rootContainerInstance.treeBaseDuration = - renderLanes.treeBaseDuration)), + (renderLanes.selfBaseDuration = type.selfBaseDuration), + (renderLanes.treeBaseDuration = type.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, @@ -5235,80 +5409,76 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + 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) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 2)) || + bubbleProperties(workInProgress), null ); } @@ -5323,9 +5493,9 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress) : null; @@ -5335,11 +5505,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5347,9 +5517,9 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress) : null @@ -5359,10 +5529,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5441,164 +5613,161 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + 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." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - 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." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$82 = finishedRoot.create; - finishedRoot.destroy = create$82(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$82 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$82; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$82 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$82, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode.canonical; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$84 = effect.create; + effect.destroy = create$84(); } - return; - case 5: - null === current && finishedWork.flags & 4 && shim(); - return; - case 6: - return; - case 4: - return; - case 12: - create$82 = finishedWork.memoizedProps.onRender; - _effect = commitTime; - "function" === typeof create$82 && - create$82( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - _effect, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - 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 detachFiberMutation(fiber) { +function detachFiberAfterEffects(fiber) { fiber.alternate = null; fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function commitWork(current, finishedWork) { @@ -5607,19 +5776,7 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedWork = current = current.next; - do { - if (3 === (finishedWork.tag & 3)) { - var destroy = finishedWork.destroy; - finishedWork.destroy = void 0; - void 0 !== destroy && destroy(); - } - finishedWork = finishedWork.next; - } while (finishedWork !== current); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 12: return; @@ -5640,7 +5797,6 @@ function commitWork(current, finishedWork) { case 1: case 5: case 6: - case 20: break a; case 3: case 4: @@ -5668,13 +5824,284 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + renderPriorityLevel = root.deletions; + if (null !== renderPriorityLevel) + for ( + firstChild = 0; + firstChild < renderPriorityLevel.length; + firstChild++ + ) { + var childToDelete = renderPriorityLevel[firstChild]; + 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; + if (void 0 !== destroy && 0 !== (tag & 2)) { + _effect = current; + var nearestMountedAncestor = root; + try { + destroy(); + } catch (error) { + captureCommitPhaseError( + _effect, + nearestMountedAncestor, + error + ); + } + } + 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 (unmountError) { + captureCommitPhaseError(current, root, unmountError); + } + 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; + childToDelete.return = null; + null !== alternate && (alternate.return = null); + } catch (error) { + captureCommitPhaseError(childToDelete, root, error); + } + } + renderPriorityLevel = root.child; + if (0 !== (root.subtreeFlags & 6454) && null !== renderPriorityLevel) + (renderPriorityLevel.return = root), (nextEffect = renderPriorityLevel); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var flags = root.flags; + if (flags & 256) { + 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)); + } + } + switch (flags & 2054) { + case 2: + root.flags &= -3; + break; + case 6: + root.flags &= -3; + commitWork(root.alternate, root); + break; + case 2048: + root.flags &= -2049; + break; + case 2052: + root.flags &= -2049; + commitWork(root.alternate, root); + break; + case 4: + commitWork(root.alternate, root); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + renderPriorityLevel = root.sibling; + if (null !== renderPriorityLevel) { + renderPriorityLevel.return = root.return; + nextEffect = renderPriorityLevel; + break; + } + nextEffect = root.return; + } + } +} +function commitLayoutEffects(finishedWork, root) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork, firstChild = root; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + if (0 !== (fiber$jscomp$0.flags & 324)) { + var current = fiber$jscomp$0.alternate; + try { + var finishedRoot = firstChild; + if (0 !== (fiber$jscomp$0.flags & 68)) + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, fiber$jscomp$0); + break; + case 1: + var instance = fiber$jscomp$0.stateNode; + if (fiber$jscomp$0.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + fiber$jscomp$0.elementType === fiber$jscomp$0.type + ? current.memoizedProps + : resolveDefaultProps( + fiber$jscomp$0.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = fiber$jscomp$0.updateQueue; + null !== updateQueue && + commitUpdateQueue(fiber$jscomp$0, updateQueue, instance); + break; + case 3: + var updateQueue$85 = fiber$jscomp$0.updateQueue; + if (null !== updateQueue$85) { + finishedRoot = null; + if (null !== fiber$jscomp$0.child) + switch (fiber$jscomp$0.child.tag) { + case 5: + finishedRoot = + fiber$jscomp$0.child.stateNode.canonical; + break; + case 1: + finishedRoot = fiber$jscomp$0.child.stateNode; + } + commitUpdateQueue( + fiber$jscomp$0, + updateQueue$85, + finishedRoot + ); + } + break; + case 5: + null === current && fiber$jscomp$0.flags & 4 && shim(); + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = fiber$jscomp$0.memoizedProps.onRender, + commitTime$88 = commitTime; + current = null === current ? "mount" : "update"; + "function" === typeof onRender && + onRender( + fiber$jscomp$0.memoizedProps.id, + current, + fiber$jscomp$0.actualDuration, + fiber$jscomp$0.treeBaseDuration, + fiber$jscomp$0.actualStartTime, + commitTime$88, + finishedRoot.memoizedInteractions + ); + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + 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." + ); + } + if (fiber$jscomp$0.flags & 256) { + finishedRoot = void 0; + var ref = fiber$jscomp$0.ref; + if (null !== ref) { + var instance$jscomp$0 = fiber$jscomp$0.stateNode; + switch (fiber$jscomp$0.tag) { + case 5: + finishedRoot = instance$jscomp$0.canonical; + break; + default: + finishedRoot = instance$jscomp$0; + } + "function" === typeof ref + ? ref(finishedRoot) + : (ref.current = finishedRoot); + } + } + } catch (error) { + captureCommitPhaseError( + fiber$jscomp$0, + fiber$jscomp$0.return, + error + ); + } + } + if (fiber$jscomp$0 === fiber) { + nextEffect = null; + break; + } + finishedRoot = fiber$jscomp$0.sibling; + if (null !== finishedRoot) { + finishedRoot.return = fiber$jscomp$0.return; + nextEffect = finishedRoot; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, @@ -5687,14 +6114,11 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -5702,17 +6126,12 @@ var ceil = Math.ceil, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, pendingPassiveEffectsLanes = 0, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, spawnedWorkDuringRender = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -5722,30 +6141,22 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } + if (0 === (fiber & 1)) return 1; + if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) + ? (fiber = findUpdateLane(12)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); + (fiber = findUpdateLane(fiber))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -5778,7 +6189,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime), schedulePendingInteractions(fiber, lane)); - mostRecentlyUpdatedRoot = fiber; + return fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -5826,45 +6237,42 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && + 0 === suspendedLanes + ? (null !== existingCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); - } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); - root.callbackPriority = currentTime; - root.callbackNode = existingCallbackNode; - } -} -function performConcurrentWorkOnRoot(root) { + (root.callbackPriority = 0)) + : root.callbackPriority !== currentTime && + (null != existingCallbackNode && + Scheduler_cancelCallback(existingCallbackNode), + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = null)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority( + currentTime + )), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))), + (root.callbackPriority = currentTime), + (root.callbackNode = existingCallbackNode)); +} +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; + currentEventTransitionLane = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -5875,8 +6283,14 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; + if (didTimeout) + return ( + (root.expiredLanes |= lanes & root.pendingLanes), + ensureRootIsScheduled(root, now()), + null + ); var lanes$jscomp$0 = lanes; - var exitStatus = executionContext; + didTimeout = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( @@ -5898,21 +6312,19 @@ function performConcurrentWorkOnRoot(root) { resetContextDependencies(); tracing.__interactionsRef.current = lanes$jscomp$0; ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = exitStatus; + executionContext = didTimeout; null !== workInProgress - ? (exitStatus = 0) + ? (didTimeout = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && + (didTimeout = workInProgressRootExitStatus)); + if (0 !== didTimeout) { + 2 === didTimeout && ((executionContext |= 64), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -5920,7 +6332,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -5930,9 +6342,9 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 125829120) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; prevDispatcher = root.suspendedLanes; @@ -5943,7 +6355,7 @@ function performConcurrentWorkOnRoot(root) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -5951,12 +6363,12 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; + if ((lanes & 8388096) === lanes) break; + didTimeout = root.eventTimes; for (prevDispatcher = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); lanes$jscomp$0 = 1 << index$4; - index$4 = exitStatus[index$4]; + index$4 = didTimeout[index$4]; index$4 > prevDispatcher && (prevDispatcher = index$4); lanes &= ~lanes$jscomp$0; } @@ -6003,9 +6415,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$9 = 31 - clz32(suspendedLanes), - lane = 1 << index$9; - root[index$9] = -1; + var index$6 = 31 - clz32(suspendedLanes), + lane = 1 << index$6; + root[index$6] = -1; suspendedLanes &= ~lane; } } @@ -6013,17 +6425,12 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( + var lanes = root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); + ? workInProgressRootRenderLanes + : getNextLanes(root, 0); + var exitStatus = renderRootSync(root, lanes); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6042,11 +6449,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6086,7 +6488,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6096,10 +6498,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } spawnedWorkDuringRender = null; } function handleError(root$jscomp$0, thrownValue) { @@ -6130,7 +6551,7 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress = null; break; } - erroredWork.mode & 8 && + erroredWork.mode & 4 && stopProfilerTimerIfRunningAndRecordDelta(erroredWork, !0); a: { var root = root$jscomp$0, @@ -6138,15 +6559,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6157,15 +6581,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$77 = returnFiber; + workInProgress$79 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { - var nextState = workInProgress$77.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$79.tag)) { + var nextState = workInProgress$79.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$77.memoizedProps; + var props = workInProgress$79.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6177,16 +6601,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$77.updateQueue; + var wakeables = workInProgress$79.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$77.updateQueue = updateQueue; + workInProgress$79.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$77.mode & 2)) { - workInProgress$77.flags |= 64; - sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + if ( + 0 === (workInProgress$79.mode & 1) && + workInProgress$79 !== returnFiber + ) { + workInProgress$79.flags |= 128; + sourceFiber.flags |= 65536; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6217,12 +6644,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$77.flags |= 8192; - workInProgress$77.lanes = thrownValue; + workInProgress$79.flags |= 16384; + workInProgress$79.lanes = thrownValue; break a; } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$79 = workInProgress$79.return; + } while (null !== workInProgress$79); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6231,47 +6658,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$77 = returnFiber; + workInProgress$79 = returnFiber; do { - switch (workInProgress$77.tag) { + switch (workInProgress$79.tag) { case 3: root = value; - workInProgress$77.flags |= 8192; + workInProgress$79.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$78 = createRootErrorUpdate( - workInProgress$77, + workInProgress$79.lanes |= thrownValue; + var update$80 = createRootErrorUpdate( + workInProgress$79, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$78); + enqueueCapturedUpdate(workInProgress$79, update$80); break a; case 1: root = value; - var ctor = workInProgress$77.type, - instance = workInProgress$77.stateNode; + var ctor = workInProgress$79.type, + instance = workInProgress$79.stateNode; if ( - 0 === (workInProgress$77.flags & 64) && + 0 === (workInProgress$79.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$77.flags |= 8192; + workInProgress$79.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$81 = createClassErrorUpdate( - workInProgress$77, + workInProgress$79.lanes |= thrownValue; + var update$83 = createClassErrorUpdate( + workInProgress$79, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$81); + enqueueCapturedUpdate(workInProgress$79, update$83); break a; } } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$79 = workInProgress$79.return; + } while (null !== workInProgress$79); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6330,7 +6757,7 @@ function workLoopConcurrent() { } function performUnitOfWork(unitOfWork) { var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 8) + 0 !== (unitOfWork.mode & 4) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current = beginWork$1(current, unitOfWork, subtreeRenderLanes)), @@ -6347,8 +6774,8 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - if (0 === (completedWork.mode & 8)) + if (0 === (completedWork.flags & 8192)) { + if (0 === (completedWork.mode & 4)) current = completeWork(current, completedWork, subtreeRenderLanes); else { var fiber = completedWork; @@ -6361,65 +6788,14 @@ function completeUnitOfWork(unitOfWork) { workInProgress = current; return; } - current = completedWork; - if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) - ) { - fiber = 0; - if (0 !== (current.mode & 8)) { - for ( - var actualDuration = current.actualDuration, - treeBaseDuration = current.selfBaseDuration, - shouldBubbleActualDurations = - null === current.alternate || - current.child !== current.alternate.child, - child = current.child; - null !== child; - - ) - (fiber |= child.lanes | child.childLanes), - shouldBubbleActualDurations && - (actualDuration += child.actualDuration), - (treeBaseDuration += child.treeBaseDuration), - (child = child.sibling); - 13 === current.tag && - null !== current.memoizedState && - ((shouldBubbleActualDurations = current.child), - null !== shouldBubbleActualDurations && - (treeBaseDuration -= - shouldBubbleActualDurations.treeBaseDuration)); - current.actualDuration = actualDuration; - current.treeBaseDuration = treeBaseDuration; - } else - for (actualDuration = current.child; null !== actualDuration; ) - (fiber |= actualDuration.lanes | actualDuration.childLanes), - (actualDuration = actualDuration.sibling); - current.childLanes = fiber; - } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } - if (0 !== (completedWork.mode & 8)) { + if (0 !== (completedWork.mode & 4)) { stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1); current = completedWork.actualDuration; for (fiber = completedWork.child; null !== fiber; ) @@ -6427,8 +6803,9 @@ function completeUnitOfWork(unitOfWork) { completedWork.actualDuration = current; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6459,271 +6836,65 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$10 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$10; - remainingLanes$jscomp$0[index$10] = 0; - eventTimes[index$10] = -1; - expirationTimes[index$10] = -1; - noLongerPendingLanes &= ~lane; - } + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && + 0 === (remainingLanes & 8) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { + remainingLanes = executionContext; executionContext |= 32; - eventTimes = pushInteractions(root); - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; + var prevInteractions = pushInteractions(root); + ReactCurrentOwner$2.current = null; + commitBeforeMutationEffects(root, finishedWork); commitTime = now$1(); - nextEffect = remainingLanes; - do - try { - for (; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - nextEffect.flags &= -3; - break; - case 6: - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - expirationTimes = nextEffect; - a: for (index$10 = noLongerPendingLanes = expirationTimes; ; ) { - lane = index$10; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, lane); - } catch (err) {} - switch (lane.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = lane.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next, - effect = firstEffect; - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (tag & 4)) - enqueuePendingPassiveHookEffectUnmount( - lane, - effect - ); - else { - _effect2 = lane; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } - } - effect = effect.next; - } while (effect !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(lane); - var instance = lane.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (effect = lane), - (_effect2 = instance), - (_effect2.props = effect.memoizedProps), - (_effect2.state = effect.memoizedState), - _effect2.componentWillUnmount(); - } catch (unmountError) { - captureCommitPhaseError(lane, unmountError); - } - break; - case 5: - safelyDetachRef(lane); - break; - case 4: - createChildNodeSet(lane.stateNode.containerInfo); - } - if (null !== index$10.child) - (index$10.child.return = index$10), - (index$10 = index$10.child); - else { - if (index$10 === noLongerPendingLanes) break; - for (; null === index$10.sibling; ) { - if ( - null === index$10.return || - index$10.return === noLongerPendingLanes - ) - break a; - index$10 = index$10.return; - } - index$10.sibling.return = index$10.return; - index$10 = index$10.sibling; - } - } - var alternate = expirationTimes.alternate; - detachFiberMutation(expirationTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$90) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$90); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); + commitMutationEffects(root, renderPriorityLevel, finishedWork); root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance$jscomp$0.canonical; - break; - default: - current = instance$jscomp$0; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$91) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$91); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; + commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - tracing.__interactionsRef.current = eventTimes; - executionContext = remainingLanes$jscomp$0; + tracing.__interactionsRef.current = prevInteractions; + executionContext = remainingLanes; } else (root.current = finishedWork), (commitTime = now$1()); - if ((flags$jscomp$0 = rootDoesHavePassiveEffects)) + if ((prevInteractions = rootDoesHavePassiveEffects)) (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes), (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (ref = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((instance$jscomp$0 = nextEffect), - (instance$jscomp$0.sibling = null), - (instance$jscomp$0.stateNode = null)), - (nextEffect = ref); remainingLanes = root.pendingLanes; if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) - for ( - ref = spawnedWorkDuringRender, - spawnedWorkDuringRender = null, - instance$jscomp$0 = 0; - instance$jscomp$0 < ref.length; - instance$jscomp$0++ - ) + if (null !== spawnedWorkDuringRender) { + var expirationTimes = spawnedWorkDuringRender; + spawnedWorkDuringRender = null; + for (var i = 0; i < expirationTimes.length; i++) scheduleInteractions( root, - ref[instance$jscomp$0], + expirationTimes[i], root.memoizedInteractions ); + } schedulePendingInteractions(root, remainingLanes); } else legacyErrorBoundariesThatAlreadyFailed = null; - flags$jscomp$0 || finishPendingInteractions(root, lanes); - 1 === remainingLanes + prevInteractions || finishPendingInteractions(root, lanes); + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - renderPriorityLevel, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6734,30 +6905,6 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6769,24 +6916,6 @@ function flushPassiveEffects() { } return !1; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects, @@ -6797,41 +6926,104 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var prevInteractions = pushInteractions(root), - unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$96 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$96.destroy; - effect$96.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); + var prevInteractions = pushInteractions(root); + for (nextEffect = root.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + if (fiber$jscomp$0 === fiberToDelete) { + nextEffect = null; + break; + } + child$jscomp$0 = fiber$jscomp$0.sibling; + if (null !== child$jscomp$0) { + child$jscomp$0.return = fiber$jscomp$0.return; + nextEffect = child$jscomp$0; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } + fiber$jscomp$0 = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); + null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); + } + nextEffect = fiber; } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$96 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; - try { - var create$100 = effect$96.create; - effect$96.destroy = create$100(); - } catch (error$101) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$101); } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + a: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + child = fiber.sibling; + if (null !== child) { + child.return = fiber.return; + nextEffect = child; + break a; + } + nextEffect = fiber.return; + } } - for (unmountEffects = root.current.firstEffect; null !== unmountEffects; ) - (create$100 = unmountEffects.nextEffect), - (unmountEffects.nextEffect = null), - unmountEffects.flags & 8 && - ((unmountEffects.sibling = null), (unmountEffects.stateNode = null)), - (unmountEffects = create$100); + for (nextEffect = fiber = root.current; null !== nextEffect; ) + if ( + ((child = nextEffect), + (deletions = child.child), + 0 !== (child.subtreeFlags & 1040) && null !== deletions) + ) + (deletions.return = child), (nextEffect = deletions); + else + a: for (child = fiber; null !== nextEffect; ) { + deletions = nextEffect; + if (0 !== (deletions.flags & 1024)) + try { + switch (deletions.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, deletions); + } + } catch (error) { + captureCommitPhaseError(deletions, deletions.return, error); + } + if (deletions === child) { + nextEffect = null; + break a; + } + i = deletions.sibling; + if (null !== i) { + i.return = deletions.return; + nextEffect = i; + break a; + } + nextEffect = deletions.return; + } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, lanes); executionContext = prevExecutionContext; @@ -6849,43 +7041,51 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { ensureRootIsScheduled(rootFiber, sourceFiber), schedulePendingInteractions(rootFiber, 1)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update), - schedulePendingInteractions(fiber, 1); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber), + schedulePendingInteractions(nearestMountedAncestor, 1)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6897,7 +7097,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 125829120) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6911,14 +7111,13 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + 0 === (wakeable & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) + : 0 === (wakeable & 2) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6935,85 +7134,90 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateLanes; - break; - case 12: - 0 !== (renderLanes & workInProgress.childLanes) && - (workInProgress.flags |= 4); - updateLanes = workInProgress.stateNode; - updateLanes.effectDuration = 0; - updateLanes.passiveEffectDuration = 0; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, + if (0 === (renderLanes & updateLanes)) { + didReceiveUpdate = !1; + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer( workInProgress, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + break; + case 10: + updateLanes = workInProgress.type._context; + var nextValue = workInProgress.memoizedProps.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = nextValue; + break; + case 12: + 0 !== (renderLanes & workInProgress.childLanes) && + (workInProgress.flags |= 4); + updateLanes = workInProgress.stateNode; + updateLanes.effectDuration = 0; + updateLanes.passiveEffectDuration = 0; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); + return null !== workInProgress ? workInProgress.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; + case 19: + updateLanes = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; + } + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); + } + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7025,22 +7229,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7050,8 +7254,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7062,9 +7266,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7076,28 +7280,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7106,7 +7310,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7115,7 +7319,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7124,8 +7328,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7133,7 +7337,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7141,32 +7345,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7177,19 +7381,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7229,16 +7432,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7279,27 +7482,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; + nextValue = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue2); - context$jscomp$0._currentValue2 = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = nextValue.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = hasContext; + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = objectIs(oldValue, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits(oldValue, hasContext) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7311,15 +7508,14 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + oldValue = workInProgress.child, + null !== oldValue && (oldValue.return = workInProgress); + null !== oldValue; ) { - var list = context$jscomp$0.dependencies; + var list = oldValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + getDerivedStateFromProps = oldValue.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7329,20 +7525,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (1 === oldValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + oldValue.lanes |= renderLanes; + dependency = oldValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(oldValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7350,16 +7550,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + 10 === oldValue.tag + ? oldValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; + : oldValue.child + : oldValue.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + getDerivedStateFromProps.return = oldValue; else for ( - getDerivedStateFromProps = context$jscomp$0; + getDerivedStateFromProps = oldValue; null !== getDerivedStateFromProps; ) { @@ -7367,20 +7567,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + oldValue = getDerivedStateFromProps.sibling; + if (null !== oldValue) { + oldValue.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = oldValue; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - context$jscomp$0 = getDerivedStateFromProps; + oldValue = getDerivedStateFromProps; } + } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7388,28 +7589,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7427,11 +7628,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7441,8 +7642,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7543,9 +7744,9 @@ function finishPendingInteractions(root, committedLanes) { if (null !== subscriber && 0 === interaction.__count) try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$102) { + } catch (error$95) { scheduleCallback(99, function() { - throw error$102; + throw error$95; }); } })); @@ -7561,8 +7762,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; this.actualDuration = 0; @@ -7603,11 +7804,11 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null), + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); + workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7644,15 +7845,18 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 8; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + 1 <= + (null == pendingProps.unstable_level + ? 1 + : pendingProps.unstable_level) && (mode |= 16); break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 4)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -7843,7 +8047,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7875,10 +8080,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_887 = { + devToolsConfig$jscomp$inline_941 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7893,11 +8098,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1087 = { - bundleType: devToolsConfig$jscomp$inline_887.bundleType, - version: devToolsConfig$jscomp$inline_887.version, - rendererPackageName: devToolsConfig$jscomp$inline_887.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_887.rendererConfig, +var internals$jscomp$inline_1218 = { + bundleType: devToolsConfig$jscomp$inline_941.bundleType, + version: devToolsConfig$jscomp$inline_941.version, + rendererPackageName: devToolsConfig$jscomp$inline_941.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_941.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7912,7 +8117,7 @@ var internals$jscomp$inline_1087 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_887.findFiberByHostInstance || + devToolsConfig$jscomp$inline_941.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -7921,16 +8126,16 @@ var internals$jscomp$inline_1087 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1088 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1219 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1088.isDisabled && - hook$jscomp$inline_1088.supportsFiber + !hook$jscomp$inline_1219.isDisabled && + hook$jscomp$inline_1219.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1088.inject( - internals$jscomp$inline_1087 + (rendererID = hook$jscomp$inline_1219.inject( + internals$jscomp$inline_1218 )), - (injectedHook = hook$jscomp$inline_1088); + (injectedHook = hook$jscomp$inline_1219); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -7973,7 +8178,7 @@ exports.render = function(element, containerTag, callback) { if (!root) { root = new FiberRootNode(containerTag, 0, !1); var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 8); + isDevToolsPresent && (JSCompiler_inline_result |= 4); JSCompiler_inline_result = createFiber( 3, null, @@ -7982,6 +8187,7 @@ exports.render = function(element, containerTag, callback) { ); root.current = JSCompiler_inline_result; JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 6b9ea503d3866e..96a631c87dd349 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -1237,10 +1237,10 @@ var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; -var FundamentalComponent = 20; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; +var CacheComponent = 24; /** * Instance of element that should respond to touch/move types of interactions, @@ -2864,12 +2864,12 @@ var REACT_SUSPENSE_TYPE = 0xead1; var REACT_SUSPENSE_LIST_TYPE = 0xead8; var REACT_MEMO_TYPE = 0xead3; var REACT_LAZY_TYPE = 0xead4; -var REACT_FUNDAMENTAL_TYPE = 0xead5; var REACT_SCOPE_TYPE = 0xead7; var REACT_OPAQUE_ID_TYPE = 0xeae0; var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; var REACT_OFFSCREEN_TYPE = 0xeae2; var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; +var REACT_CACHE_TYPE = 0xeae4; if (typeof Symbol === "function" && Symbol.for) { var symbolFor = Symbol.for; @@ -2885,12 +2885,12 @@ if (typeof Symbol === "function" && Symbol.for) { REACT_SUSPENSE_LIST_TYPE = symbolFor("react.suspense_list"); REACT_MEMO_TYPE = symbolFor("react.memo"); REACT_LAZY_TYPE = symbolFor("react.lazy"); - REACT_FUNDAMENTAL_TYPE = symbolFor("react.fundamental"); REACT_SCOPE_TYPE = symbolFor("react.scope"); REACT_OPAQUE_ID_TYPE = symbolFor("react.opaque.id"); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2964,6 +2964,9 @@ function getComponentName(type) { case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + + case REACT_CACHE_TYPE: + return "Cache"; } if (typeof type === "object") { @@ -3001,9 +3004,10 @@ function getComponentName(type) { // The rest of the flags are static for better dead code elimination. var enableProfilerTimer = true; -var enableFundamentalAPI = false; +var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; +var deferRenderPhaseUpdateToNextBatch = true; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -3021,53 +3025,84 @@ var Update = 4; var PlacementAndUpdate = /* */ - 6; -var Deletion = - /* */ - 8; + Placement | Update; +var ChildDeletion = + /* */ + 16; var ContentReset = /* */ - 16; + 32; var Callback = /* */ - 32; + 64; var DidCapture = /* */ - 64; + 128; var Ref = /* */ - 128; + 256; var Snapshot = /* */ - 256; + 512; var Passive = /* */ - 512; + 1024; var Hydrating = /* */ - 1024; + 2048; var HydratingAndUpdate = /* */ - 1028; + Hydrating | Update; +var Visibility = + /* */ + 4096; var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ - 4095; // These are not really side effects, but we still reuse this field. + 8191; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ - 4096; + 8192; var ShouldCapture = /* */ - 8192; // TODO (effects) Remove this bit once the new reconciler is synced to the old. + 16384; // TODO (effects) Remove this bit once the new reconciler is synced to the old. var PassiveUnmountPendingDev = /* */ - 16384; + 32768; var ForceUpdateForLegacySuspense = /* */ - 32768; // Static tags describe aspects of a fiber that are not specific to a render, + 65536; // Static tags describe aspects of a fiber that are not specific to a render, +// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). +// This enables us to defer more work in the unmount case, +// since we can defer traversing the tree during layout to look for Passive effects, +// and instead rely on the static flag as a signal that there may be cleanup work. + +var PassiveStatic = + /* */ + 131072; // These flags allow us to traverse to fibers that have effects on mount +// don't contain effects, by checking subtreeFlags. + +var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity + // flag logic (see #20043) + Update | Snapshot | 0; +var MutationMask = + Placement | + Update | + ChildDeletion | + ContentReset | + Ref | + Hydrating | + Visibility; +var LayoutMask = Update | Callback | Ref; // TODO: Split into PassiveMountMask and PassiveUnmountMask + +var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. +// This allows certain concepts to persist without recalculting them, +// e.g. whether a subtree contains passive effects or portals. + +var StaticMask = PassiveStatic; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -3307,38 +3342,28 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null + ? findCurrentHostFiberImpl(currentParent) + : null; +} - if (!currentParent) { - return null; - } // Next we'll drill down this component to find the first HostComponent/Text. - - var node = currentParent; - - while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - return node; - } else if (node.child) { - node.child.return = node; - node = node.child; - continue; - } +function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } - if (node === currentParent) { - return null; - } + var child = node.child; - while (!node.sibling) { - if (!node.return || node.return === currentParent) { - return null; - } + while (child !== null) { + var match = findCurrentHostFiberImpl(child); - node = node.return; + if (match !== null) { + return match; } - node.sibling.return = node.return; - node = node.sibling; - } // Flow needs the return null here, but ESLint complains about it. - // eslint-disable-next-line no-unreachable + child = child.sibling; + } return null; } @@ -3959,2090 +3984,2139 @@ var ReactNativeFiberHostComponent = /*#__PURE__*/ (function() { return ReactNativeFiberHostComponent; })(); // eslint-disable-next-line no-unused-expressions -// can re-export everything from this module. +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -function shim() { - { +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { throw Error( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" ); } -} // Hydration (when unsupported) -var isSuspenseInstancePending = shim; -var isSuspenseInstanceFallback = shim; -var hydrateTextInstance = shim; +} -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; -var UPDATE_SIGNAL = {}; +// Except for NoPriority, these correspond to Scheduler priorities. We use +// ascending numbers so we can compare them like numbers. They start at 90 to +// avoid clashing with Scheduler's priorities. +var ImmediatePriority = 99; +var UserBlockingPriority = 98; +var NormalPriority = 97; +var LowPriority = 96; +var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. -{ - Object.freeze(UPDATE_SIGNAL); -} // Counter for uniquely identifying views. -// % 10 === 1 means it is a rootTag. -// % 2 === 0 means it is a Fabric tag. +var NoPriority = 90; +var shouldYield = Scheduler_shouldYield; +var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. + Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; +var syncQueue = null; +var immediateQueueCallbackNode = null; +var isFlushingSyncQueue = false; +var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. +// This will be the case for modern browsers that support `performance.now`. In +// older browsers, Scheduler falls back to `Date.now`, which returns a Unix +// timestamp. In that case, subtract the module initialization time to simulate +// the behavior of performance.now and keep our times small enough to fit +// within 32 bits. +// TODO: Consider lifting this into Scheduler. -var nextReactTag = 3; +var now = + initialTimeMs < 10000 + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return ImmediatePriority; -function allocateTag() { - var tag = nextReactTag; + case Scheduler_UserBlockingPriority: + return UserBlockingPriority; - if (tag % 10 === 1) { - tag += 2; - } + case Scheduler_NormalPriority: + return NormalPriority; - nextReactTag = tag + 2; - return tag; -} + case Scheduler_LowPriority: + return LowPriority; -function recursivelyUncacheFiberNode(node) { - if (typeof node === "number") { - // Leaf node (eg text) - uncacheFiberNode(node); - } else { - uncacheFiberNode(node._nativeTag); + case Scheduler_IdlePriority: + return IdlePriority; - node._children.forEach(recursivelyUncacheFiberNode); + default: { + throw Error("Unknown priority level."); + } } } -function appendInitialChild(parentInstance, child) { - parentInstance._children.push(child); -} -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = allocateTag(); - var viewConfig = getViewConfigForType(type); - { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); - } +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case ImmediatePriority: + return Scheduler_ImmediatePriority; + + case UserBlockingPriority: + return Scheduler_UserBlockingPriority; + + case NormalPriority: + return Scheduler_NormalPriority; + + case LowPriority: + return Scheduler_LowPriority; + + case IdlePriority: + return Scheduler_IdlePriority; + + default: { + throw Error("Unknown priority level."); } } +} - var updatePayload = create(props, viewConfig.validAttributes); - ReactNativePrivateInterface.UIManager.createView( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload // props - ); - var component = new ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandle - ); - precacheFiberNode(internalInstanceHandle, tag); - updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined - // in the same file but if it's external it can't see the types. +function runWithPriority(reactPriorityLevel, fn) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(priorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(priorityLevel, callback, options); +} +function scheduleSyncCallback(callback) { + // Push this callback into an internal queue. We'll flush these either in + // the next tick, or earlier if something calls `flushSyncCallbackQueue`. + if (syncQueue === null) { + syncQueue = [callback]; // TODO: Figure out how to remove this It's only here as a last resort if we + // forget to explicitly flush. - return component; + { + // Flush the queue in the next tick. + immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ); + } + } else { + // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); + } } -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - if (!hostContext.isInAParentText) { - throw Error("Text strings must be rendered within a component."); +function cancelCallback(callbackNode) { + Scheduler_cancelCallback(callbackNode); +} +function flushSyncCallbackQueue() { + if (immediateQueueCallbackNode !== null) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); } - var tag = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { - text: text - } // props - ); - precacheFiberNode(internalInstanceHandle, tag); - return tag; + flushSyncCallbackQueueImpl(); } -function finalizeInitialChildren( - parentInstance, - type, - props, - rootContainerInstance, - hostContext -) { - // Don't send a no-op message over the bridge. - if (parentInstance._children.length === 0) { - return false; - } // Map from child objects to native tags. - // Either way we need to pass a copy of the Array to prevent it from being frozen. - var nativeTags = parentInstance._children.map(function(child) { - return typeof child === "number" - ? child // Leaf node (eg text) - : child._nativeTag; - }); +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { + // Prevent re-entrancy. + isFlushingSyncQueue = true; + var i = 0; - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance._nativeTag, // containerTag - nativeTags // reactTags - ); - return false; -} -function getRootHostContext(rootContainerInstance) { - return { - isInAParentText: false - }; -} -function getChildHostContext(parentHostContext, type, rootContainerInstance) { - var prevIsInAParentText = parentHostContext.isInAParentText; - var isInAParentText = - type === "AndroidTextInput" || // Android - type === "RCTMultilineTextInputView" || // iOS - type === "RCTSinglelineTextInputView" || // iOS - type === "RCTText" || - type === "RCTVirtualText"; + { + try { + var _isSync2 = true; + var _queue = syncQueue; + runWithPriority(ImmediatePriority, function() { + for (; i < _queue.length; i++) { + var callback = _queue[i]; - if (prevIsInAParentText !== isInAParentText) { - return { - isInAParentText: isInAParentText - }; - } else { - return parentHostContext; - } -} -function getPublicInstance(instance) { - return instance; -} -function prepareForCommit(containerInfo) { - // Noop - return null; -} -function prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - hostContext -) { - return UPDATE_SIGNAL; -} -function resetAfterCommit(containerInfo) { - // Noop -} -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; -function shouldSetTextContent(type, props) { - // TODO (bvaughn) Revisit this decision. - // Always returning false simplifies the createInstance() implementation, - // But creates an additional child Fiber for raw text children. - // No additional native views are created though. - // It's not clear to me which is better so I'm deferring for now. - // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 - return false; -} // ------------------- -function appendChild(parentInstance, child) { - var childTag = typeof child === "number" ? child : child._nativeTag; - var children = parentInstance._children; - var index = children.indexOf(child); + do { + callback = callback(_isSync2); + } while (callback !== null); + } + }); + syncQueue = null; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); + } // Resume flushing in the next tick - if (index >= 0) { - children.splice(index, 1); - children.push(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerTag - [index], // moveFromIndices - [children.length - 1], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [] // removeAtIndices - ); - } else { - children.push(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerTag - [], // moveFromIndices - [], // moveToIndices - [childTag], // addChildReactTags - [children.length - 1], // addAtIndices - [] // removeAtIndices - ); + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ); + throw error; + } finally { + isFlushingSyncQueue = false; + } + } } } -function appendChildToContainer(parentInstance, child) { - var childTag = typeof child === "number" ? child : child._nativeTag; - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance, // containerTag - [childTag] // reactTags - ); -} -function commitTextUpdate(textInstance, oldText, newText) { - ReactNativePrivateInterface.UIManager.updateView( - textInstance, // reactTag - "RCTRawText", // viewName - { - text: newText - } // props - ); -} -function commitUpdate( - instance, - updatePayloadTODO, - type, - oldProps, - newProps, - internalInstanceHandle -) { - var viewConfig = instance.viewConfig; - updateFiberProps(instance._nativeTag, newProps); - var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. - // This is an expensive no-op for Android, and causes an unnecessary - // view invalidation for certain components (eg RCTTextInput) on iOS. - if (updatePayload != null) { - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, // reactTag - viewConfig.uiViewClassName, // viewName - updatePayload // props - ); +var SyncLanePriority = 15; +var SyncBatchedLanePriority = 14; +var InputDiscreteHydrationLanePriority = 13; +var InputDiscreteLanePriority = 12; +var InputContinuousHydrationLanePriority = 11; +var InputContinuousLanePriority = 10; +var DefaultHydrationLanePriority = 9; +var DefaultLanePriority = 8; +var TransitionHydrationPriority = 7; +var TransitionPriority = 6; +var RetryLanePriority = 5; +var SelectiveHydrationLanePriority = 4; +var IdleHydrationLanePriority = 3; +var IdleLanePriority = 2; +var OffscreenLanePriority = 1; +var NoLanePriority = 0; // Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler. +// If those values are changed that package should be rebuilt and redeployed. + +var TotalLanes = 31; +var NoLanes = + /* */ + 0; +var NoLane = + /* */ + 0; +var SyncLane = + /* */ + 1; +var SyncBatchedLane = + /* */ + 2; +var InputDiscreteHydrationLane = + /* */ + 4; +var InputDiscreteLane = + /* */ + 8; +var InputContinuousHydrationLane = + /* */ + 16; +var InputContinuousLane = + /* */ + 32; +var DefaultHydrationLane = + /* */ + 64; +var DefaultLane = + /* */ + 128; +var TransitionHydrationLane = + /* */ + 256; +var TransitionLanes = + /* */ + 8388096; +var TransitionLane1 = + /* */ + 512; +var TransitionLane2 = + /* */ + 1024; +var TransitionLane3 = + /* */ + 2048; +var TransitionLane4 = + /* */ + 4096; +var TransitionLane5 = + /* */ + 8192; +var TransitionLane6 = + /* */ + 16384; +var TransitionLane7 = + /* */ + 32768; +var TransitionLane8 = + /* */ + 65536; +var TransitionLane9 = + /* */ + 131072; +var TransitionLane10 = + /* */ + 262144; +var TransitionLane11 = + /* */ + 524288; +var TransitionLane12 = + /* */ + 1048576; +var TransitionLane13 = + /* */ + 2097152; +var TransitionLane14 = + /* */ + 4194304; +var RetryLanes = + /* */ + 125829120; +var RetryLane1 = + /* */ + 8388608; +var RetryLane2 = + /* */ + 16777216; +var RetryLane3 = + /* */ + 33554432; +var RetryLane4 = + /* */ + 67108864; +var SomeRetryLane = RetryLane1; +var SelectiveHydrationLane = + /* */ + 134217728; +var NonIdleLanes = + /* */ + 268435455; +var IdleHydrationLane = + /* */ + 268435456; +var IdleLane = + /* */ + 536870912; +var OffscreenLane = + /* */ + 1073741824; // This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler) +var NoTimestamp = -1; +var nextTransitionLane = TransitionLane1; +var nextRetryLane = RetryLane1; +// Used by getHighestPriorityLanes and getNextLanes: + +var return_highestLanePriority = DefaultLanePriority; + +function getHighestPriorityLanes(lanes) { + switch (getHighestPriorityLane(lanes)) { + case SyncLane: + return_highestLanePriority = SyncLanePriority; + return SyncLane; + + case SyncBatchedLane: + return_highestLanePriority = SyncBatchedLanePriority; + return SyncBatchedLane; + + case InputDiscreteHydrationLane: + return_highestLanePriority = InputDiscreteHydrationLanePriority; + return InputDiscreteHydrationLane; + + case InputDiscreteLane: + return_highestLanePriority = InputDiscreteLanePriority; + return InputDiscreteLane; + + case InputContinuousHydrationLane: + return_highestLanePriority = InputContinuousHydrationLanePriority; + return InputContinuousHydrationLane; + + case InputContinuousLane: + return_highestLanePriority = InputContinuousLanePriority; + return InputContinuousLane; + + case DefaultHydrationLane: + return_highestLanePriority = DefaultHydrationLanePriority; + return DefaultHydrationLane; + + case DefaultLane: + return_highestLanePriority = DefaultLanePriority; + return DefaultLane; + + case TransitionHydrationLane: + return_highestLanePriority = TransitionHydrationPriority; + return TransitionHydrationLane; + + 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: + return_highestLanePriority = TransitionPriority; + return lanes & TransitionLanes; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + return_highestLanePriority = RetryLanePriority; + return lanes & RetryLanes; + + case SelectiveHydrationLane: + return_highestLanePriority = SelectiveHydrationLanePriority; + return SelectiveHydrationLane; + + case IdleHydrationLane: + return_highestLanePriority = IdleHydrationLanePriority; + return IdleHydrationLane; + + case IdleLane: + return_highestLanePriority = IdleLanePriority; + return IdleLane; + + case OffscreenLane: + return_highestLanePriority = OffscreenLanePriority; + return OffscreenLane; + + default: + { + error("Should have found matching lanes. This is a bug in React."); + } // This shouldn't be reachable, but as a fallback, return the entire bitmask. + + return_highestLanePriority = DefaultLanePriority; + return lanes; } } -function insertBefore(parentInstance, child, beforeChild) { - var children = parentInstance._children; - var index = children.indexOf(child); // Move existing child or add new child? - if (index >= 0) { - children.splice(index, 1); - var beforeChildIndex = children.indexOf(beforeChild); - children.splice(beforeChildIndex, 0, child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [index], // moveFromIndices - [beforeChildIndex], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [] // removeAtIndices - ); - } else { - var _beforeChildIndex = children.indexOf(beforeChild); - - children.splice(_beforeChildIndex, 0, child); - var childTag = typeof child === "number" ? child : child._nativeTag; - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [], // moveFromIndices - [], // moveToIndices - [childTag], // addChildReactTags - [_beforeChildIndex], // addAtIndices - [] // removeAtIndices - ); - } -} -function insertInContainerBefore(parentInstance, child, beforeChild) { - // TODO (bvaughn): Remove this check when... - // We create a wrapper object for the container in ReactNative render() - // Or we refactor to remove wrapper objects entirely. - // For more info on pros/cons see PR #8560 description. - if (!(typeof parentInstance !== "number")) { - throw Error("Container does not support insertBefore operation"); - } -} -function removeChild(parentInstance, child) { - recursivelyUncacheFiberNode(child); - var children = parentInstance._children; - var index = children.indexOf(child); - children.splice(index, 1); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [], // moveFromIndices - [], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [index] // removeAtIndices - ); -} -function removeChildFromContainer(parentInstance, child) { - recursivelyUncacheFiberNode(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance, // containerID - [], // moveFromIndices - [], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [0] // removeAtIndices - ); -} -function resetTextContent(instance) { - // Noop -} -function hideInstance(instance) { - var viewConfig = instance.viewConfig; - var updatePayload = create( - { - style: { - display: "none" - } - }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -function hideTextInstance(textInstance) { - throw new Error("Not yet implemented."); -} -function unhideInstance(instance, props) { - var viewConfig = instance.viewConfig; - var updatePayload = diff( - Object.assign({}, props, { - style: [ - props.style, - { - display: "none" - } - ] - }), - props, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -function clearContainer(container) { - // TODO Implement this for React Native - // UIManager does not expose a "remove all" type method. -} -function unhideTextInstance(textInstance, text) { - throw new Error("Not yet implemented."); -} -function makeClientIdInDEV(warnOnAccessInDEV) { - throw new Error("Not yet implemented"); -} -function preparePortalMount(portalInstance) { - // noop -} - -// Helpers to patch console.logs to avoid logging during side-effect free -// replaying on render function. This currently only patches the object -// lazily which won't cover if the log function was extracted eagerly. -// We could also eagerly patch the method. -var disabledDepth = 0; -var prevLog; -var prevInfo; -var prevWarn; -var prevError; -var prevGroup; -var prevGroupCollapsed; -var prevGroupEnd; - -function disabledLog() {} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case ImmediatePriority: + return SyncLanePriority; -disabledLog.__reactDisabledLog = true; -function disableLogs() { - { - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - prevLog = console.log; - prevInfo = console.info; - prevWarn = console.warn; - prevError = console.error; - prevGroup = console.group; - prevGroupCollapsed = console.groupCollapsed; - prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 + case UserBlockingPriority: + return InputContinuousLanePriority; - var props = { - configurable: true, - enumerable: true, - value: disabledLog, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. + case NormalPriority: + case LowPriority: + // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. + return DefaultLanePriority; - Object.defineProperties(console, { - info: props, - log: props, - warn: props, - error: props, - group: props, - groupCollapsed: props, - groupEnd: props - }); - /* eslint-enable react-internal/no-production-logging */ - } + case IdlePriority: + return IdleLanePriority; - disabledDepth++; + default: + return NoLanePriority; } } -function reenableLogs() { - { - disabledDepth--; +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case SyncLanePriority: + case SyncBatchedLanePriority: + return ImmediatePriority; - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - var props = { - configurable: true, - enumerable: true, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. + case InputDiscreteHydrationLanePriority: + case InputDiscreteLanePriority: + case InputContinuousHydrationLanePriority: + case InputContinuousLanePriority: + return UserBlockingPriority; - Object.defineProperties(console, { - log: Object.assign({}, props, { - value: prevLog - }), - info: Object.assign({}, props, { - value: prevInfo - }), - warn: Object.assign({}, props, { - value: prevWarn - }), - error: Object.assign({}, props, { - value: prevError - }), - group: Object.assign({}, props, { - value: prevGroup - }), - groupCollapsed: Object.assign({}, props, { - value: prevGroupCollapsed - }), - groupEnd: Object.assign({}, props, { - value: prevGroupEnd - }) - }); - /* eslint-enable react-internal/no-production-logging */ - } + case DefaultHydrationLanePriority: + case DefaultLanePriority: + case TransitionHydrationPriority: + case TransitionPriority: + case SelectiveHydrationLanePriority: + case RetryLanePriority: + return NormalPriority; - if (disabledDepth < 0) { - error( - "disabledDepth fell below zero. " + - "This is a bug in React. Please file an issue." - ); - } - } -} + case IdleHydrationLanePriority: + case IdleLanePriority: + case OffscreenLanePriority: + return IdlePriority; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -function describeBuiltInComponentFrame(name, source, ownerFn) { - { - var ownerName = null; + case NoLanePriority: + return NoPriority; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; + default: { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); } - - return describeComponentFrame(name, source, ownerName); } } -var componentFrameCache; +function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; -{ - var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap(); -} -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; + if (pendingLanes === NoLanes) { + return_highestLanePriority = NoLanePriority; + return NoLanes; + } -function describeComponentFrame(name, source, ownerName) { - var sourceInfo = ""; + var nextLanes = NoLanes; + var nextLanePriority = NoLanePriority; + var expiredLanes = root.expiredLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; // Check if any work has expired. - if (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: - // prefer "folder/index.js" instead of just "index.js". + if (expiredLanes !== NoLanes) { + // TODO: Should entangle with SyncLane + nextLanes = expiredLanes; + nextLanePriority = return_highestLanePriority = SyncLanePriority; + } else { + // Do not work on any idle work until all the non-idle work has finished, + // even if the work is suspended. + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - if (/^index\./.test(fileName)) { - var match = path.match(BEFORE_SLASH_RE); + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; - if (match) { - var pathBeforeSlash = match[1]; + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); + nextLanePriority = return_highestLanePriority; } } - } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + nextLanePriority = return_highestLanePriority; + } + } + } } - return "\n in " + (name || "Unknown") + sourceInfo; -} + if (nextLanes === NoLanes) { + // This should only be reachable if we're suspended + // TODO: Consider warning in this path if a fallback timer is not scheduled. + return NoLanes; + } // If we're already in the middle of a render, switching lanes will interrupt + // it and we'll lose our progress. We should only do this if the new lanes are + // higher priority. -function describeClassComponentFrame(ctor, source, ownerFn) { - { - return describeFunctionComponentFrame(ctor, source, ownerFn); - } -} -function describeFunctionComponentFrame(fn, source, ownerFn) { - { - if (!fn) { - return ""; + if ( + wipLanes !== NoLanes && + wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't + // bother waiting until the root is complete. + (wipLanes & suspendedLanes) === NoLanes + ) { + getHighestPriorityLanes(wipLanes); + var wipLanePriority = return_highestLanePriority; + + if ( + nextLanePriority <= wipLanePriority || // Default priority updates should not interrupt transition updates. The + // only difference between default updates and transition updates is that + // default updates do not support refresh transitions. + (nextLanePriority === DefaultLanePriority && + wipLanePriority === TransitionPriority) + ) { + // Keep working on the existing in-progress tree. Do not interrupt. + return wipLanes; + } else { + return_highestLanePriority = nextLanePriority; } + } // Check for entangled lanes and add them to the batch. + // + // A lane is said to be entangled with another when it's not allowed to render + // in a batch that does not also include the other lane. Typically we do this + // when multiple updates have the same source, and we only want to respond to + // the most recent event from that source. + // + // Note that we apply entanglements *after* checking for partial work above. + // This means that if a lane is entangled during an interleaved event while + // it's already rendering, we won't interrupt it. This is intentional, since + // entanglement is usually "best effort": we'll try our best to render the + // lanes in the same batch, but it's not worth throwing out partially + // completed work in order to do it. + // TODO: Reconsider this. The counter-argument is that the partial work + // represents an intermediate state, which we don't want to show to the user. + // And by spending extra time finishing it, we're increasing the amount of + // time it takes to show the final state, which is what they are actually + // waiting for. + // + // For those exceptions where entanglement is semantically important, like + // useMutableSource, we should ensure that there is no partial work at the + // time we apply the entanglement. - var name = fn.displayName || fn.name || null; - var ownerName = null; + var entangledLanes = root.entangledLanes; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + if (entangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = nextLanes & entangledLanes; - return describeComponentFrame(name, source, ownerName); + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + nextLanes |= entanglements[index]; + lanes &= ~lane; + } } + + return nextLanes; } +function getMostRecentEventTime(root, lanes) { + var eventTimes = root.eventTimes; + var mostRecentEventTime = NoTimestamp; -function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { - if (type == null) { - return ""; - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var eventTime = eventTimes[index]; - if (typeof type === "function") { - { - return describeFunctionComponentFrame(type, source, ownerFn); + if (eventTime > mostRecentEventTime) { + mostRecentEventTime = eventTime; } - } - if (typeof type === "string") { - return describeBuiltInComponentFrame(type, source, ownerFn); + lanes &= ~lane; } - switch (type) { - case REACT_SUSPENSE_TYPE: - return describeBuiltInComponentFrame("Suspense", source, ownerFn); + return mostRecentEventTime; +} - case REACT_SUSPENSE_LIST_TYPE: - return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); +function computeExpirationTime(lane, currentTime) { + // TODO: Expiration heuristic is constant per lane, so could use a map. + getHighestPriorityLanes(lane); + var priority = return_highestLanePriority; + + if (priority >= InputContinuousLanePriority) { + // User interactions should expire slightly more quickly. + // + // NOTE: This is set to the corresponding constant as in Scheduler.js. When + // we made it larger, a product metric in www regressed, suggesting there's + // a user interaction that's being starved by a series of synchronous + // updates. If that theory is correct, the proper solution is to fix the + // starvation. However, this scenario supports the idea that expiration + // times are an important safeguard when starvation does happen. + // + // Also note that, in the case of user input specifically, this will soon no + // longer be an issue because we plan to make user input synchronous by + // default (until you enter `startTransition`, of course.) + // + // If weren't planning to make these updates synchronous soon anyway, I + // would probably make this number a configurable parameter. + return currentTime + 250; + } else if (priority >= TransitionPriority) { + return currentTime + 5000; + } else { + // Anything idle priority or lower should never expire. + return NoTimestamp; } +} - if (typeof type === "object") { - switch (type.$$typeof) { - case REACT_FORWARD_REF_TYPE: - return describeFunctionComponentFrame(type.render, source, ownerFn); +function markStarvedLanesAsExpired(root, currentTime) { + // TODO: This gets called every time we yield. We can optimize by storing + // the earliest expiration time on the root. Then use that to quickly bail out + // of this function. + var pendingLanes = root.pendingLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; + var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their + // expiration time. If so, we'll assume the update is being starved and mark + // it as expired to force it to finish. - case REACT_MEMO_TYPE: - // Memo may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + var lanes = pendingLanes; - case REACT_LAZY_TYPE: { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; - try { - // Lazy may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV( - init(payload), - source, - ownerFn - ); - } catch (x) {} + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); } + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; } - } - return ""; -} + lanes &= ~lane; + } +} // This returns the highest priority pending lanes regardless of whether they +function getLanesToRetrySynchronouslyOnError(root) { + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; -var loggedTypeFailures = {}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } -function setCurrentlyValidatingElement(element) { - { - if (element) { - var owner = element._owner; - var stack = describeUnknownElementTypeFrameInDEV( - element.type, - element._source, - owner ? owner.type : null - ); - ReactDebugCurrentFrame.setExtraStackFrame(stack); - } else { - ReactDebugCurrentFrame.setExtraStackFrame(null); - } + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } -} -function checkPropTypes(typeSpecs, values, location, componentName, element) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); + return NoLanes; +} +function returnNextLanesPriority() { + return return_highestLanePriority; +} +function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; +} +function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; +} +function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; +} +function isTransitionLane(lane) { + return (lane & TransitionLanes) !== 0; +} // To ensure consistency across multiple updates in the same event, this should +// be a pure function, so that it always returns the same lane for given inputs. - for (var typeSpecName in typeSpecs) { - if (has(typeSpecs, typeSpecName)) { - var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case NoLanePriority: + break; - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - if (typeof typeSpecs[typeSpecName] !== "function") { - var err = Error( - (componentName || "React class") + - ": " + - location + - " type `" + - typeSpecName + - "` is invalid; " + - "it must be a function, usually from the `prop-types` package, but received `" + - typeof typeSpecs[typeSpecName] + - "`." + - "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." - ); - err.name = "Invariant Violation"; - throw err; - } + case SyncLanePriority: + return SyncLane; - error$1 = typeSpecs[typeSpecName]( - values, - typeSpecName, - componentName, - location, - null, - "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" - ); - } catch (ex) { - error$1 = ex; - } + case SyncBatchedLanePriority: + return SyncBatchedLane; - if (error$1 && !(error$1 instanceof Error)) { - setCurrentlyValidatingElement(element); + case InputDiscreteLanePriority: + return InputDiscreteLane; - error( - "%s: type specification of %s" + - " `%s` is invalid; the type checker " + - "function must return `null` or an `Error` but returned a %s. " + - "You may have forgotten to pass an argument to the type checker " + - "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + - "shape all require an argument).", - componentName || "React class", - location, - typeSpecName, - typeof error$1 - ); + case InputContinuousLanePriority: + return InputContinuousLane; - setCurrentlyValidatingElement(null); - } + case DefaultLanePriority: + return DefaultLane; - if ( - error$1 instanceof Error && - !(error$1.message in loggedTypeFailures) - ) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error$1.message] = true; - setCurrentlyValidatingElement(element); + case TransitionPriority: // Should be handled by findTransitionLane instead - error("Failed %s type: %s", location, error$1.message); + case RetryLanePriority: + // Should be handled by findRetryLane instead + break; - setCurrentlyValidatingElement(null); - } - } - } + case IdleLanePriority: + return IdleLane; } -} -var valueStack = []; -var fiberStack; - -{ - fiberStack = []; + { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } } +function claimNextTransitionLane() { + // Cycle through the lanes, assigning each new transition to the next lane. + // In most cases, this means every transition gets its own lane, until we + // run out of lanes and cycle back to the beginning. + var lane = nextTransitionLane; + nextTransitionLane <<= 1; -var index = -1; + if ((nextTransitionLane & TransitionLanes) === 0) { + nextTransitionLane = TransitionLane1; + } -function createCursor(defaultValue) { - return { - current: defaultValue - }; + return lane; } +function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; -function pop(cursor, fiber) { - if (index < 0) { - { - error("Unexpected pop."); - } - - return; - } - - { - if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); - } + if ((nextRetryLane & RetryLanes) === 0) { + nextRetryLane = RetryLane1; } - cursor.current = valueStack[index]; - valueStack[index] = null; - - { - fiberStack[index] = null; - } + return lane; +} - index--; +function getHighestPriorityLane(lanes) { + return lanes & -lanes; } -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; +function pickArbitraryLane(lanes) { + // This wrapper function gets inlined. Only exists so to communicate that it + // doesn't matter which bit is selected; you can pick any bit without + // affecting the algorithms where its used. Here I'm using + // getHighestPriorityLane because it requires the fewest operations. + return getHighestPriorityLane(lanes); +} - { - fiberStack[index] = fiber; - } +function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); +} - cursor.current = value; +function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); } -var warnedAboutMissingGetChildContext; +function includesSomeLane(a, b) { + return (a & b) !== NoLanes; +} +function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; +} +function mergeLanes(a, b) { + return a | b; +} +function removeLanes(set, subset) { + return set & ~subset; +} +function intersectLanes(a, b) { + return a & b; +} // Seems redundant, but it changes the type from a single lane (used for +// updates) to a group of lanes (used for flushing work). -{ - warnedAboutMissingGetChildContext = {}; +function laneToLanes(lane) { + return lane; } +function createLaneMap(initial) { + // Intentionally pushing one by one. + // https://v8.dev/blog/elements-kinds#avoid-creating-holes + var laneMap = []; -var emptyContextObject = {}; + for (var i = 0; i < TotalLanes; i++) { + laneMap.push(initial); + } -{ - Object.freeze(emptyContextObject); -} // A cursor to the current merged context object on the stack. + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update + // could unblock them. Clear the suspended lanes so that we can try rendering + // them again. + // + // TODO: We really only need to unsuspend only lanes that are in the + // `subtreeLanes` of the updated fiber, or the update lanes of the return + // path. This would exclude suspended updates in an unrelated sibling tree, + // since there's no way for this update to unblock it. + // + // We don't do this if the incoming update is idle, because we never process + // idle updates until after all the regular updates have finished; there's no + // way it could unblock a transition. -var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. + if (updateLane !== IdleLane) { + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; + } -var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. -// We use this to get access to the parent context after we have already -// pushed the next context provider, and now need to merge their contexts. + var eventTimes = root.eventTimes; + var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most + // recent event, and we assume time is monotonically increasing. -var previousContext = emptyContextObject; + eventTimes[index] = eventTime; +} +function markRootSuspended(root, suspendedLanes) { + root.suspendedLanes |= suspendedLanes; + root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. -function getUnmaskedContext( - workInProgress, - Component, - didPushOwnContextIfProvider -) { - { - if (didPushOwnContextIfProvider && isContextProvider(Component)) { - // If the fiber is a context provider itself, when we read its context - // we may have already pushed its own child context on the stack. A context - // provider should not "see" its own child context. Therefore we read the - // previous (parent) context instead for a context provider. - return previousContext; - } + var expirationTimes = root.expirationTimes; + var lanes = suspendedLanes; - return contextStackCursor.current; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } - -function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { - var instance = workInProgress.stateNode; - instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; - instance.__reactInternalMemoizedMaskedChildContext = maskedContext; - } +function markRootPinged(root, pingedLanes, eventTime) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; } +function markRootExpired(root, expiredLanes) { + root.expiredLanes |= expiredLanes & root.pendingLanes; +} +function hasDiscreteLanes(lanes) { + return (lanes & InputDiscreteLane) !== NoLanes; +} +function markRootMutableRead(root, updateLane) { + root.mutableReadLanes |= updateLane & root.pendingLanes; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again -function getMaskedContext(workInProgress, unmaskedContext) { - { - var type = workInProgress.type; - var contextTypes = type.contextTypes; - - if (!contextTypes) { - return emptyContextObject; - } // Avoid recreating masked context unless unmasked context has changed. - // Failing to do this will result in unnecessary calls to componentWillReceiveProps. - // This may trigger infinite loops if componentWillReceiveProps calls setState. - - var instance = workInProgress.stateNode; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; - if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext - ) { - return instance.__reactInternalMemoizedMaskedChildContext; - } + var entanglements = root.entanglements; + var eventTimes = root.eventTimes; + var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work - var context = {}; + var lanes = noLongerPendingLanes; - for (var key in contextTypes) { - context[key] = unmaskedContext[key]; - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + eventTimes[index] = NoTimestamp; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + // In addition to entangling each of the given lanes with each other, we also + // have to consider _transitive_ entanglements. For each lane that is already + // entangled with *any* of the given lanes, that lane is now transitively + // entangled with *all* the given lanes. + // + // Translated: If C is entangled with A, then entangling A with B also + // entangles C with B. + // + // If this is hard to grasp, it might help to intentionally break this + // function and look at the tests that fail in ReactTransition-test.js. Try + // commenting out one of the conditions below. + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + var entanglements = root.entanglements; + var lanes = rootEntangledLanes; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); - } // Cache unmasked context so we can avoid recreating masked context unless necessary. - // Context is created before the class component is instantiated so check for instance. + while (lanes) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; - if (instance) { - cacheContext(workInProgress, unmaskedContext, context); + if ( + // Is this one of the newly entangled lanes? + (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? + (entanglements[index] & entangledLanes) + ) { + entanglements[index] |= entangledLanes; } - return context; + lanes &= ~lane; } } +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. +// Based on: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -function hasContextChanged() { - { - return didPerformWorkStackCursor.current; - } -} +var log = Math.log; +var LN2 = Math.LN2; -function isContextProvider(type) { - { - var childContextTypes = type.childContextTypes; - return childContextTypes !== null && childContextTypes !== undefined; +function clz32Fallback(lanes) { + if (lanes === 0) { + return 32; } + + return (31 - ((log(lanes) / LN2) | 0)) | 0; } -function popContext(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_now$1 = Scheduler.unstable_now; + +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); } } +var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -function popTopLevelContextObject(fiber) { +// can re-export everything from this module. + +function shim() { { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); + throw Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ); } -} +} // Hydration (when unsupported) +var isSuspenseInstancePending = shim; +var isSuspenseInstanceFallback = shim; +var hydrateTextInstance = shim; -function pushTopLevelContextObject(fiber, context, didChange) { - { - if (!(contextStackCursor.current === emptyContextObject)) { - throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." - ); - } +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; +var UPDATE_SIGNAL = {}; - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); - } -} +{ + Object.freeze(UPDATE_SIGNAL); +} // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. -function processChildContext(fiber, type, parentContext) { - { - var instance = fiber.stateNode; - var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. - // It has only been added in Fiber to match the (unintentional) behavior in Stack. +var nextReactTag = 3; - if (typeof instance.getChildContext !== "function") { - { - var componentName = getComponentName(type) || "Unknown"; +function allocateTag() { + var tag = nextReactTag; - if (!warnedAboutMissingGetChildContext[componentName]) { - warnedAboutMissingGetChildContext[componentName] = true; + if (tag % 10 === 1) { + tag += 2; + } - error( - "%s.childContextTypes is specified but there is no getChildContext() method " + - "on the instance. You can either define getChildContext() on %s or remove " + - "childContextTypes from it.", - componentName, - componentName - ); - } - } + nextReactTag = tag + 2; + return tag; +} - return parentContext; - } +function recursivelyUncacheFiberNode(node) { + if (typeof node === "number") { + // Leaf node (eg text) + uncacheFiberNode(node); + } else { + uncacheFiberNode(node._nativeTag); - var childContext = instance.getChildContext(); + node._children.forEach(recursivelyUncacheFiberNode); + } +} +function appendInitialChild(parentInstance, child) { + parentInstance._children.push(child); +} +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + var tag = allocateTag(); + var viewConfig = getViewConfigForType(type); - for (var contextKey in childContext) { - if (!(contextKey in childContextTypes)) { - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] ); } } + } - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); - } + var updatePayload = create(props, viewConfig.validAttributes); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload // props + ); + var component = new ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandle + ); + precacheFiberNode(internalInstanceHandle, tag); + updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined + // in the same file but if it's external it can't see the types. - return Object.assign({}, parentContext, childContext); - } + return component; } +function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + if (!hostContext.isInAParentText) { + throw Error("Text strings must be rendered within a component."); + } -function pushContextProvider(workInProgress) { - { - var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. - // If the instance does not exist yet, we will push null at first, - // and replace it on the stack later when invalidating the context. + var tag = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag + { + text: text + } // props + ); + precacheFiberNode(internalInstanceHandle, tag); + return tag; +} +function finalizeInitialChildren( + parentInstance, + type, + props, + rootContainerInstance, + hostContext +) { + // Don't send a no-op message over the bridge. + if (parentInstance._children.length === 0) { + return false; + } // Map from child objects to native tags. + // Either way we need to pass a copy of the Array to prevent it from being frozen. - var memoizedMergedChildContext = - (instance && instance.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; // Remember the parent context so we can merge with it later. - // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + var nativeTags = parentInstance._children.map(function(child) { + return typeof child === "number" + ? child // Leaf node (eg text) + : child._nativeTag; + }); - previousContext = contextStackCursor.current; - push(contextStackCursor, memoizedMergedChildContext, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); - return true; - } + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance._nativeTag, // containerTag + nativeTags // reactTags + ); + return false; } +function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; +} +function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; -function invalidateContextProvider(workInProgress, type, didChange) { - { - var instance = workInProgress.stateNode; - - if (!instance) { - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); - } - - if (didChange) { - // Merge parent and own context. - // Skip this if we're not updating due to sCU. - // This avoids unnecessarily recomputing memoized values. - var mergedContext = processChildContext( - workInProgress, - type, - previousContext - ); - instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. - // It is important to unwind the context in the reverse order. - - pop(didPerformWorkStackCursor, workInProgress); - pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. - - push(contextStackCursor, mergedContext, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } else { - pop(didPerformWorkStackCursor, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText + }; + } else { + return parentHostContext; } } +function getPublicInstance(instance) { + return instance; +} +function prepareForCommit(containerInfo) { + // Noop + return null; +} +function prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + hostContext +) { + return UPDATE_SIGNAL; +} +function resetAfterCommit(containerInfo) { + // Noop +} +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; +function shouldSetTextContent(type, props) { + // TODO (bvaughn) Revisit this decision. + // Always returning false simplifies the createInstance() implementation, + // But creates an additional child Fiber for raw text children. + // No additional native views are created though. + // It's not clear to me which is better so I'm deferring for now. + // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 + return false; +} +function appendChild(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + var children = parentInstance._children; + var index = children.indexOf(child); -function findCurrentUnmaskedContext(fiber) { - { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw Error( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." - ); - } - - var node = fiber; - - do { - switch (node.tag) { - case HostRoot: - return node.stateNode.context; - - case ClassComponent: { - var Component = node.type; - - if (isContextProvider(Component)) { - return node.stateNode.__reactInternalMemoizedMergedChildContext; - } - - break; - } - } - - node = node.return; - } while (node !== null); - - { - throw Error( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + if (index >= 0) { + children.splice(index, 1); + children.push(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerTag + [index], // moveFromIndices + [children.length - 1], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); + } else { + children.push(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerTag + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [children.length - 1], // addAtIndices + [] // removeAtIndices + ); } } +function appendChildToContainer(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance, // containerTag + [childTag] // reactTags + ); +} +function commitTextUpdate(textInstance, oldText, newText) { + ReactNativePrivateInterface.UIManager.updateView( + textInstance, // reactTag + "RCTRawText", // viewName + { + text: newText + } // props + ); +} +function commitUpdate( + instance, + updatePayloadTODO, + type, + oldProps, + newProps, + internalInstanceHandle +) { + var viewConfig = instance.viewConfig; + updateFiberProps(instance._nativeTag, newProps); + var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. + // This is an expensive no-op for Android, and causes an unnecessary + // view invalidation for certain components (eg RCTTextInput) on iOS. -var LegacyRoot = 0; -var BlockingRoot = 1; -var ConcurrentRoot = 2; - -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; + if (updatePayload != null) { + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, // reactTag + viewConfig.uiViewClassName, // viewName + updatePayload // props + ); } +} +function insertBefore(parentInstance, child, beforeChild) { + var children = parentInstance._children; + var index = children.indexOf(child); // Move existing child or add new child? - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (index >= 0) { + children.splice(index, 1); + var beforeChildIndex = children.indexOf(beforeChild); + children.splice(beforeChildIndex, 0, child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [index], // moveFromIndices + [beforeChildIndex], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); + } else { + var _beforeChildIndex = children.indexOf(beforeChild); - if (hook.isDisabled) { - // This isn't a real property on the hook, but it can be set to opt out - // of DevTools integration and associated warnings and logs. - // https://github.com/facebook/react/issues/3877 - return true; + children.splice(_beforeChildIndex, 0, child); + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [_beforeChildIndex], // addAtIndices + [] // removeAtIndices + ); } - - if (!hook.supportsFiber) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. - - return true; +} +function insertInContainerBefore(parentInstance, child, beforeChild) { + // TODO (bvaughn): Remove this check when... + // We create a wrapper object for the container in ReactNative render() + // Or we refactor to remove wrapper objects entirely. + // For more info on pros/cons see PR #8560 description. + if (!(typeof parentInstance !== "number")) { + throw Error("Container does not support insertBefore operation"); } +} +function removeChild(parentInstance, child) { + recursivelyUncacheFiberNode(child); + var children = parentInstance._children; + var index = children.indexOf(child); + children.splice(index, 1); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [index] // removeAtIndices + ); +} +function removeChildFromContainer(parentInstance, child) { + recursivelyUncacheFiberNode(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [0] // removeAtIndices + ); +} +function resetTextContent(instance) { + // Noop +} +function hideInstance(instance) { + var viewConfig = instance.viewConfig; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); +} +function hideTextInstance(textInstance) { + throw new Error("Not yet implemented."); +} +function unhideInstance(instance, props) { + var viewConfig = instance.viewConfig; + var updatePayload = diff( + Object.assign({}, props, { + style: [ + props.style, + { + display: "none" + } + ] + }), + props, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); +} +function clearContainer(container) { + // TODO Implement this for React Native + // UIManager does not expose a "remove all" type method. +} +function unhideTextInstance(textInstance, text) { + throw new Error("Not yet implemented."); +} +function makeClientIdInDEV(warnOnAccessInDEV) { + throw new Error("Not yet implemented"); +} +function preparePortalMount(portalInstance) { + // noop +} - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. +// Helpers to patch console.logs to avoid logging during side-effect free +// replaying on render function. This currently only patches the object +// lazily which won't cover if the log function was extracted eagerly. +// We could also eagerly patch the method. +var disabledDepth = 0; +var prevLog; +var prevInfo; +var prevWarn; +var prevError; +var prevGroup; +var prevGroupCollapsed; +var prevGroupEnd; - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists +function disabledLog() {} - return true; -} -function onScheduleRoot(root, children) { +disabledLog.__reactDisabledLog = true; +function disableLogs() { { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 - error("React instrumentation encountered an error: %s", err); - } - } + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. + + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + /* eslint-enable react-internal/no-production-logging */ } + + disabledDepth++; } } -function onCommitRoot(root, priorityLevel) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; +function reenableLogs() { + { + disabledDepth--; - if (enableProfilerTimer) { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + var props = { + configurable: true, + enumerable: true, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. - error("React instrumentation encountered an error: %s", err); - } - } + Object.defineProperties(console, { + log: Object.assign({}, props, { + value: prevLog + }), + info: Object.assign({}, props, { + value: prevInfo + }), + warn: Object.assign({}, props, { + value: prevWarn + }), + error: Object.assign({}, props, { + value: prevError + }), + group: Object.assign({}, props, { + value: prevGroup + }), + groupCollapsed: Object.assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: Object.assign({}, props, { + value: prevGroupEnd + }) + }); + /* eslint-enable react-internal/no-production-logging */ + } + + if (disabledDepth < 0) { + error( + "disabledDepth fell below zero. " + + "This is a bug in React. Please file an issue." + ); } } } -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - error("React instrumentation encountered an error: %s", err); - } - } +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +function describeBuiltInComponentFrame(name, source, ownerFn) { + { + var ownerName = null; + + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; } + + return describeComponentFrame(name, source, ownerName); } } - -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_now = Scheduler.unstable_now; +var componentFrameCache; { - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); - } + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); } -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -var ImmediatePriority = 99; -var UserBlockingPriority = 98; -var NormalPriority = 97; -var LowPriority = 96; -var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - -var NoPriority = 90; -var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; -var SyncLanePriority = 15; -var SyncBatchedLanePriority = 14; -var InputDiscreteHydrationLanePriority = 13; -var InputDiscreteLanePriority = 12; -var InputContinuousHydrationLanePriority = 11; -var InputContinuousLanePriority = 10; -var DefaultHydrationLanePriority = 9; -var DefaultLanePriority = 8; -var TransitionHydrationPriority = 7; -var TransitionPriority = 6; -var RetryLanePriority = 5; -var SelectiveHydrationLanePriority = 4; -var IdleHydrationLanePriority = 3; -var IdleLanePriority = 2; -var OffscreenLanePriority = 1; -var NoLanePriority = 0; -var TotalLanes = 31; -var NoLanes = - /* */ - 0; -var NoLane = - /* */ - 0; -var SyncLane = - /* */ - 1; -var SyncBatchedLane = - /* */ - 2; -var InputDiscreteHydrationLane = - /* */ - 4; -var InputDiscreteLanes = - /* */ - 24; -var InputContinuousHydrationLane = - /* */ - 32; -var InputContinuousLanes = - /* */ - 192; -var DefaultHydrationLane = - /* */ - 256; -var DefaultLanes = - /* */ - 3584; -var TransitionHydrationLane = - /* */ - 4096; -var TransitionLanes = - /* */ - 4186112; -var RetryLanes = - /* */ - 62914560; -var SomeRetryLane = - /* */ - 33554432; -var SelectiveHydrationLane = - /* */ - 67108864; -var NonIdleLanes = - /* */ - 134217727; -var IdleHydrationLane = - /* */ - 134217728; -var IdleLanes = - /* */ - 805306368; -var OffscreenLane = - /* */ - 1073741824; -var NoTimestamp = -1; -// Used by getHighestPriorityLanes and getNextLanes: + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: + // prefer "folder/index.js" instead of just "index.js". -var return_highestLanePriority = DefaultLanePriority; + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); -function getHighestPriorityLanes(lanes) { - if ((SyncLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncLanePriority; - return SyncLane; - } + if (match) { + var pathBeforeSlash = match[1]; - if ((SyncBatchedLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncBatchedLanePriority; - return SyncBatchedLane; - } + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } + } + } - if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { - return_highestLanePriority = InputDiscreteHydrationLanePriority; - return InputDiscreteHydrationLane; + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } - var inputDiscreteLanes = InputDiscreteLanes & lanes; + return "\n in " + (name || "Unknown") + sourceInfo; +} - if (inputDiscreteLanes !== NoLanes) { - return_highestLanePriority = InputDiscreteLanePriority; - return inputDiscreteLanes; +function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeFunctionComponentFrame(ctor, source, ownerFn); } +} +function describeFunctionComponentFrame(fn, source, ownerFn) { + { + if (!fn) { + return ""; + } - if ((lanes & InputContinuousHydrationLane) !== NoLanes) { - return_highestLanePriority = InputContinuousHydrationLanePriority; - return InputContinuousHydrationLane; - } + var name = fn.displayName || fn.name || null; + var ownerName = null; - var inputContinuousLanes = InputContinuousLanes & lanes; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - if (inputContinuousLanes !== NoLanes) { - return_highestLanePriority = InputContinuousLanePriority; - return inputContinuousLanes; + return describeComponentFrame(name, source, ownerName); } +} - if ((lanes & DefaultHydrationLane) !== NoLanes) { - return_highestLanePriority = DefaultHydrationLanePriority; - return DefaultHydrationLane; +function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; } - var defaultLanes = DefaultLanes & lanes; - - if (defaultLanes !== NoLanes) { - return_highestLanePriority = DefaultLanePriority; - return defaultLanes; + if (typeof type === "function") { + { + return describeFunctionComponentFrame(type, source, ownerFn); + } } - if ((lanes & TransitionHydrationLane) !== NoLanes) { - return_highestLanePriority = TransitionHydrationPriority; - return TransitionHydrationLane; + if (typeof type === "string") { + return describeBuiltInComponentFrame(type, source, ownerFn); } - var transitionLanes = TransitionLanes & lanes; + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense", source, ownerFn); - if (transitionLanes !== NoLanes) { - return_highestLanePriority = TransitionPriority; - return transitionLanes; + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); } - var retryLanes = RetryLanes & lanes; + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render, source, ownerFn); - if (retryLanes !== NoLanes) { - return_highestLanePriority = RetryLanePriority; - return retryLanes; - } + case REACT_MEMO_TYPE: + // Memo may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); - if (lanes & SelectiveHydrationLane) { - return_highestLanePriority = SelectiveHydrationLanePriority; - return SelectiveHydrationLane; - } + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; - if ((lanes & IdleHydrationLane) !== NoLanes) { - return_highestLanePriority = IdleHydrationLanePriority; - return IdleHydrationLane; + try { + // Lazy may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV( + init(payload), + source, + ownerFn + ); + } catch (x) {} + } + } } - var idleLanes = IdleLanes & lanes; + return ""; +} - if (idleLanes !== NoLanes) { - return_highestLanePriority = IdleLanePriority; - return idleLanes; - } +var loggedTypeFailures = {}; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - if ((OffscreenLane & lanes) !== NoLanes) { - return_highestLanePriority = OffscreenLanePriority; - return OffscreenLane; +function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV( + element.type, + element._source, + owner ? owner.type : null + ); + ReactDebugCurrentFrame.setExtraStackFrame(stack); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); + } } +} +function checkPropTypes(typeSpecs, values, location, componentName, element) { { - error("Should have found matching lanes. This is a bug in React."); - } // This shouldn't be reachable, but as a fallback, return the entire bitmask. + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(Object.prototype.hasOwnProperty); - return_highestLanePriority = DefaultLanePriority; - return lanes; -} + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case ImmediatePriority: - return SyncLanePriority; + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error( + (componentName || "React class") + + ": " + + location + + " type `" + + typeSpecName + + "` is invalid; " + + "it must be a function, usually from the `prop-types` package, but received `" + + typeof typeSpecs[typeSpecName] + + "`." + + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." + ); + err.name = "Invariant Violation"; + throw err; + } - case UserBlockingPriority: - return InputContinuousLanePriority; + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - case NormalPriority: - case LowPriority: - // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. - return DefaultLanePriority; + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); - case IdlePriority: - return IdleLanePriority; + error( + "%s: type specification of %s" + + " `%s` is invalid; the type checker " + + "function must return `null` or an `Error` but returned a %s. " + + "You may have forgotten to pass an argument to the type checker " + + "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + + "shape all require an argument).", + componentName || "React class", + location, + typeSpecName, + typeof error$1 + ); - default: - return NoLanePriority; + setCurrentlyValidatingElement(null); + } + + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); + + error("Failed %s type: %s", location, error$1.message); + + setCurrentlyValidatingElement(null); + } + } + } } } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case SyncLanePriority: - case SyncBatchedLanePriority: - return ImmediatePriority; - case InputDiscreteHydrationLanePriority: - case InputDiscreteLanePriority: - case InputContinuousHydrationLanePriority: - case InputContinuousLanePriority: - return UserBlockingPriority; +var valueStack = []; +var fiberStack; - case DefaultHydrationLanePriority: - case DefaultLanePriority: - case TransitionHydrationPriority: - case TransitionPriority: - case SelectiveHydrationLanePriority: - case RetryLanePriority: - return NormalPriority; +{ + fiberStack = []; +} - case IdleHydrationLanePriority: - case IdleLanePriority: - case OffscreenLanePriority: - return IdlePriority; +var index = -1; - case NoLanePriority: - return NoPriority; +function createCursor(defaultValue) { + return { + current: defaultValue + }; +} - default: { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); +function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); } - } -} -function getNextLanes(root, wipLanes) { - // Early bailout if there's no pending work left. - var pendingLanes = root.pendingLanes; - if (pendingLanes === NoLanes) { - return_highestLanePriority = NoLanePriority; - return NoLanes; + return; } - var nextLanes = NoLanes; - var nextLanePriority = NoLanePriority; - var expiredLanes = root.expiredLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; // Check if any work has expired. + { + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } + } - if (expiredLanes !== NoLanes) { - nextLanes = expiredLanes; - nextLanePriority = return_highestLanePriority = SyncLanePriority; - } else { - // Do not work on any idle work until all the non-idle work has finished, - // even if the work is suspended. - var nonIdlePendingLanes = pendingLanes & NonIdleLanes; + cursor.current = valueStack[index]; + valueStack[index] = null; - if (nonIdlePendingLanes !== NoLanes) { - var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + { + fiberStack[index] = null; + } - if (nonIdleUnblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; + index--; +} - if (nonIdlePingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } else { - // The only remaining work is Idle. - var unblockedLanes = pendingLanes & ~suspendedLanes; +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; - if (unblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(unblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - if (pingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(pingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } + { + fiberStack[index] = fiber; } - if (nextLanes === NoLanes) { - // This should only be reachable if we're suspended - // TODO: Consider warning in this path if a fallback timer is not scheduled. - return NoLanes; - } // If there are higher priority lanes, we'll include them even if they - // are suspended. + cursor.current = value; +} - nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt - // it and we'll lose our progress. We should only do this if the new lanes are - // higher priority. +var warnedAboutMissingGetChildContext; - if ( - wipLanes !== NoLanes && - wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't - // bother waiting until the root is complete. - (wipLanes & suspendedLanes) === NoLanes - ) { - getHighestPriorityLanes(wipLanes); - var wipLanePriority = return_highestLanePriority; +{ + warnedAboutMissingGetChildContext = {}; +} - if (nextLanePriority <= wipLanePriority) { - return wipLanes; - } else { - return_highestLanePriority = nextLanePriority; - } - } // Check for entangled lanes and add them to the batch. - // - // A lane is said to be entangled with another when it's not allowed to render - // in a batch that does not also include the other lane. Typically we do this - // when multiple updates have the same source, and we only want to respond to - // the most recent event from that source. - // - // Note that we apply entanglements *after* checking for partial work above. - // This means that if a lane is entangled during an interleaved event while - // it's already rendering, we won't interrupt it. This is intentional, since - // entanglement is usually "best effort": we'll try our best to render the - // lanes in the same batch, but it's not worth throwing out partially - // completed work in order to do it. - // - // For those exceptions where entanglement is semantically important, like - // useMutableSource, we should ensure that there is no partial work at the - // time we apply the entanglement. +var emptyContextObject = {}; - var entangledLanes = root.entangledLanes; +{ + Object.freeze(emptyContextObject); +} // A cursor to the current merged context object on the stack. - if (entangledLanes !== NoLanes) { - var entanglements = root.entanglements; - var lanes = nextLanes & entangledLanes; +var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - nextLanes |= entanglements[index]; - lanes &= ~lane; +var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. +// We use this to get access to the parent context after we have already +// pushed the next context provider, and now need to merge their contexts. + +var previousContext = emptyContextObject; + +function getUnmaskedContext( + workInProgress, + Component, + didPushOwnContextIfProvider +) { + { + if (didPushOwnContextIfProvider && isContextProvider(Component)) { + // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; } + + return contextStackCursor.current; } +} - return nextLanes; +function cacheContext(workInProgress, unmaskedContext, maskedContext) { + { + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + } } -function getMostRecentEventTime(root, lanes) { - var eventTimes = root.eventTimes; - var mostRecentEventTime = NoTimestamp; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var eventTime = eventTimes[index]; +function getMaskedContext(workInProgress, unmaskedContext) { + { + var type = workInProgress.type; + var contextTypes = type.contextTypes; - if (eventTime > mostRecentEventTime) { - mostRecentEventTime = eventTime; + if (!contextTypes) { + return emptyContextObject; + } // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. + + var instance = workInProgress.stateNode; + + if ( + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + ) { + return instance.__reactInternalMemoizedMaskedChildContext; } - lanes &= ~lane; - } + var context = {}; - return mostRecentEventTime; -} + for (var key in contextTypes) { + context[key] = unmaskedContext[key]; + } -function computeExpirationTime(lane, currentTime) { - // TODO: Expiration heuristic is constant per lane, so could use a map. - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + // Context is created before the class component is instantiated so check for instance. - if (priority >= InputContinuousLanePriority) { - // User interactions should expire slightly more quickly. - // - // NOTE: This is set to the corresponding constant as in Scheduler.js. When - // we made it larger, a product metric in www regressed, suggesting there's - // a user interaction that's being starved by a series of synchronous - // updates. If that theory is correct, the proper solution is to fix the - // starvation. However, this scenario supports the idea that expiration - // times are an important safeguard when starvation does happen. - // - // Also note that, in the case of user input specifically, this will soon no - // longer be an issue because we plan to make user input synchronous by - // default (until you enter `startTransition`, of course.) - // - // If weren't planning to make these updates synchronous soon anyway, I - // would probably make this number a configurable parameter. - return currentTime + 250; - } else if (priority >= TransitionPriority) { - return currentTime + 5000; - } else { - // Anything idle priority or lower should never expire. - return NoTimestamp; + if (instance) { + cacheContext(workInProgress, unmaskedContext, context); + } + + return context; } } -function markStarvedLanesAsExpired(root, currentTime) { - // TODO: This gets called every time we yield. We can optimize by storing - // the earliest expiration time on the root. Then use that to quickly bail out - // of this function. - var pendingLanes = root.pendingLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; - var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their - // expiration time. If so, we'll assume the update is being starved and mark - // it as expired to force it to finish. - - var lanes = pendingLanes; - - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var expirationTime = expirationTimes[index]; - - if (expirationTime === NoTimestamp) { - // Found a pending lane with no expiration time. If it's not suspended, or - // if it's pinged, assume it's CPU-bound. Compute a new expiration time - // using the current time. - if ( - (lane & suspendedLanes) === NoLanes || - (lane & pingedLanes) !== NoLanes - ) { - // Assumes timestamps are monotonically increasing. - expirationTimes[index] = computeExpirationTime(lane, currentTime); - } - } else if (expirationTime <= currentTime) { - // This lane expired - root.expiredLanes |= lane; - } - - lanes &= ~lane; +function hasContextChanged() { + { + return didPerformWorkStackCursor.current; } -} // This returns the highest priority pending lanes regardless of whether they -function getLanesToRetrySynchronouslyOnError(root) { - var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; +} - if (everythingButOffscreen !== NoLanes) { - return everythingButOffscreen; +function isContextProvider(type) { + { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; } +} - if (everythingButOffscreen & OffscreenLane) { - return OffscreenLane; +function popContext(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } - - return NoLanes; -} -function returnNextLanesPriority() { - return return_highestLanePriority; -} -function includesNonIdleWork(lanes) { - return (lanes & NonIdleLanes) !== NoLanes; -} -function includesOnlyRetries(lanes) { - return (lanes & RetryLanes) === lanes; } -function includesOnlyTransitions(lanes) { - return (lanes & TransitionLanes) === lanes; -} // To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. - -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case NoLanePriority: - break; - case SyncLanePriority: - return SyncLane; +function popTopLevelContextObject(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } +} - case SyncBatchedLanePriority: - return SyncBatchedLane; +function pushTopLevelContextObject(fiber, context, didChange) { + { + if (!(contextStackCursor.current === emptyContextObject)) { + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); + } - case InputDiscreteLanePriority: { - var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); + } +} - if (_lane === NoLane) { - // Shift to the next priority level - return findUpdateLane(InputContinuousLanePriority, wipLanes); - } +function processChildContext(fiber, type, parentContext) { + { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. - return _lane; - } + if (typeof instance.getChildContext !== "function") { + { + var componentName = getComponentName(type) || "Unknown"; - case InputContinuousLanePriority: { - var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; - if (_lane2 === NoLane) { - // Shift to the next priority level - return findUpdateLane(DefaultLanePriority, wipLanes); + error( + "%s.childContextTypes is specified but there is no getChildContext() method " + + "on the instance. You can either define getChildContext() on %s or remove " + + "childContextTypes from it.", + componentName, + componentName + ); + } } - return _lane2; + return parentContext; } - case DefaultLanePriority: { - var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); - - if (_lane3 === NoLane) { - // If all the default lanes are already being worked on, look for a - // lane in the transition range. - _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); + var childContext = instance.getChildContext(); - if (_lane3 === NoLane) { - // All the transition lanes are taken, too. This should be very - // rare, but as a last resort, pick a default lane. This will have - // the effect of interrupting the current work-in-progress render. - _lane3 = pickArbitraryLane(DefaultLanes); - } + for (var contextKey in childContext) { + if (!(contextKey in childContextTypes)) { + throw Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); } - - return _lane3; } - case TransitionPriority: // Should be handled by findTransitionLane instead + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); + } - case RetryLanePriority: - // Should be handled by findRetryLane instead - break; + return Object.assign({}, parentContext, childContext); + } +} - case IdleLanePriority: - var lane = pickArbitraryLane(IdleLanes & ~wipLanes); +function pushContextProvider(workInProgress) { + { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. - if (lane === NoLane) { - lane = pickArbitraryLane(IdleLanes); - } + var memoizedMergedChildContext = + (instance && instance.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. - return lane; + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); + return true; } +} +function invalidateContextProvider(workInProgress, type, didChange) { { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. + var instance = workInProgress.stateNode; + + if (!instance) { + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); + } -function findTransitionLane(wipLanes, pendingLanes) { - // First look for lanes that are completely unclaimed, i.e. have no - // pending work. - var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext( + workInProgress, + type, + previousContext + ); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. - if (lane === NoLane) { - // If all lanes have pending work, look for a lane that isn't currently - // being worked on. - lane = pickArbitraryLane(TransitionLanes & ~wipLanes); + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. - if (lane === NoLane) { - // If everything is being worked on, pick any lane. This has the - // effect of interrupting the current work-in-progress. - lane = pickArbitraryLane(TransitionLanes); + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } } +} - return lane; -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. +function findCurrentUnmaskedContext(fiber) { + { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ); + } -function findRetryLane(wipLanes) { - // This is a fork of `findUpdateLane` designed specifically for Suspense - // "retries" — a special update that attempts to flip a Suspense boundary - // from its placeholder state to its primary/resolved state. - var lane = pickArbitraryLane(RetryLanes & ~wipLanes); + var node = fiber; - if (lane === NoLane) { - lane = pickArbitraryLane(RetryLanes); - } + do { + switch (node.tag) { + case HostRoot: + return node.stateNode.context; - return lane; -} + case ClassComponent: { + var Component = node.type; -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} + if (isContextProvider(Component)) { + return node.stateNode.__reactInternalMemoizedMergedChildContext; + } -function getLowestPriorityLane(lanes) { - // This finds the most significant non-zero bit. - var index = 31 - clz32(lanes); - return index < 0 ? NoLanes : 1 << index; -} + break; + } + } -function getEqualOrHigherPriorityLanes(lanes) { - return (getLowestPriorityLane(lanes) << 1) - 1; -} + node = node.return; + } while (node !== null); -function pickArbitraryLane(lanes) { - // This wrapper function gets inlined. Only exists so to communicate that it - // doesn't matter which bit is selected; you can pick any bit without - // affecting the algorithms where its used. Here I'm using - // getHighestPriorityLane because it requires the fewest operations. - return getHighestPriorityLane(lanes); + { + throw Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ); + } + } } -function pickArbitraryLaneIndex(lanes) { - return 31 - clz32(lanes); -} +var LegacyRoot = 0; +var BlockingRoot = 1; +var ConcurrentRoot = 2; -function laneToIndex(lane) { - return pickArbitraryLaneIndex(lane); -} +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; + } -function includesSomeLane(a, b) { - return (a & b) !== NoLanes; -} -function isSubsetOfLanes(set, subset) { - return (set & subset) === subset; -} -function mergeLanes(a, b) { - return a | b; -} -function removeLanes(set, subset) { - return set & ~subset; -} // Seems redundant, but it changes the type from a single lane (used for -// updates) to a group of lanes (used for flushing work). - -function laneToLanes(lane) { - return lane; -} -function createLaneMap(initial) { - // Intentionally pushing one by one. - // https://v8.dev/blog/elements-kinds#avoid-creating-holes - var laneMap = []; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - for (var i = 0; i < TotalLanes; i++) { - laneMap.push(initial); + if (hook.isDisabled) { + // This isn't a real property on the hook, but it can be set to opt out + // of DevTools integration and associated warnings and logs. + // https://github.com/facebook/react/issues/3877 + return true; } - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But - // it's not practical to try every single possible combination. We need a - // heuristic to decide which lanes to attempt to render, and in which batches. - // For now, we use the same heuristic as in the old ExpirationTimes model: - // retry any lane at equal or lower priority, but don't try updates at higher - // priority without also including the lower priority updates. This works well - // when considering updates across different priority levels, but isn't - // sufficient for updates within the same priority, since we want to treat - // those updates as parallel. - // Unsuspend any update at equal or lower priority. - - var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 - - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - var eventTimes = root.eventTimes; - var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most - // recent event, and we assume time is monotonically increasing. - - eventTimes[index] = eventTime; -} -function markRootSuspended(root, suspendedLanes) { - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. - - var expirationTimes = root.expirationTimes; - var lanes = suspendedLanes; + if (!hook.supportsFiber) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; + return true; } -} -function markRootPinged(root, pingedLanes, eventTime) { - root.pingedLanes |= root.suspendedLanes & pingedLanes; -} -function hasDiscreteLanes(lanes) { - return (lanes & InputDiscreteLanes) !== NoLanes; -} -function markRootMutableRead(root, updateLane) { - root.mutableReadLanes |= updateLane & root.pendingLanes; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; // Let's try everything again - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - var entanglements = root.entanglements; - var eventTimes = root.eventTimes; - var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - var lanes = noLongerPendingLanes; + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] = NoLanes; - eventTimes[index] = NoTimestamp; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } + return true; } -function markRootEntangled(root, entangledLanes) { - root.entangledLanes |= entangledLanes; - var entanglements = root.entanglements; - var lanes = entangledLanes; +function onScheduleRoot(root, children) { + { + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { + try { + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] |= entangledLanes; - lanes &= ~lane; + error("React instrumentation encountered an error: %s", err); + } + } + } } } -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. -// Based on: -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 +function onCommitRoot(root, priorityLevel) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; -var log = Math.log; -var LN2 = Math.LN2; + if (enableProfilerTimer) { + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + didError + ); + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; -function clz32Fallback(lanes) { - if (lanes === 0) { - return 32; + error("React instrumentation encountered an error: %s", err); + } + } + } } - - return (31 - ((log(lanes) / LN2) | 0)) | 0; } +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; - -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); + error("React instrumentation encountered an error: %s", err); + } + } + } } } -var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. - -var ImmediatePriority$1 = 99; -var UserBlockingPriority$1 = 98; -var NormalPriority$1 = 97; -var LowPriority$1 = 96; -var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. +var NoFlags$1 = + /* */ + 0; // Represents whether effect should fire. -var NoPriority$1 = 90; -var shouldYield = Scheduler_shouldYield; -var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. - Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; -var syncQueue = null; -var immediateQueueCallbackNode = null; -var isFlushingSyncQueue = false; -var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// This will be the case for modern browsers that support `performance.now`. In -// older browsers, Scheduler falls back to `Date.now`, which returns a Unix -// timestamp. In that case, subtract the module initialization time to simulate -// the behavior of performance.now and keep our times small enough to fit -// within 32 bits. -// TODO: Consider lifting this into Scheduler. +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. -var now = - initialTimeMs$1 < 10000 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return ImmediatePriority$1; +var Layout = + /* */ + 2; +var Passive$1 = + /* */ + 4; - case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; +// TODO: this is special because it gets imported during build. +// +// TODO: 17.0.2 has not been released to NPM; +// It exists as a placeholder so that DevTools can support work tag changes between releases. +// When we next publish a release (either 17.0.2 or 17.1.0), update the matching TODO in backend/renderer.js +var ReactVersion = "17.0.2"; - case Scheduler_NormalPriority: - return NormalPriority$1; +var NoMode = + /* */ + 0; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root tag instead - case Scheduler_LowPriority: - return LowPriority$1; +var BlockingMode = + /* */ + 1; +var ConcurrentMode = + /* */ + 2; +var ProfileMode = + /* */ + 4; +var DebugTracingMode = + /* */ + 8; +var StrictLegacyMode = + /* */ + 16; - case Scheduler_IdlePriority: - return IdlePriority$1; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +var NoTransition = 0; +function requestCurrentTransition() { + return ReactCurrentBatchConfig.transition; +} - default: { - throw Error("Unknown priority level."); - } - } -} - -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case ImmediatePriority$1: - return Scheduler_ImmediatePriority; - - case UserBlockingPriority$1: - return Scheduler_UserBlockingPriority; - - case NormalPriority$1: - return Scheduler_NormalPriority; - - case LowPriority$1: - return Scheduler_LowPriority; - - case IdlePriority$1: - return Scheduler_IdlePriority; - - default: { - throw Error("Unknown priority level."); - } - } -} - -function runWithPriority(reactPriorityLevel, fn) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(priorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(priorityLevel, callback, options); -} -function scheduleSyncCallback(callback) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushSyncCallbackQueue`. - if (syncQueue === null) { - syncQueue = [callback]; // Flush the queue in the next tick, at the earliest. - - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ); - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - syncQueue.push(callback); - } - - return fakeCallbackNode; -} -function cancelCallback(callbackNode) { - if (callbackNode !== fakeCallbackNode) { - Scheduler_cancelCallback(callbackNode); - } -} -function flushSyncCallbackQueue() { - if (immediateQueueCallbackNode !== null) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - - flushSyncCallbackQueueImpl(); -} - -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && syncQueue !== null) { - // Prevent re-entrancy. - isFlushingSyncQueue = true; - var i = 0; - - { - try { - var _isSync2 = true; - var _queue = syncQueue; - runWithPriority(ImmediatePriority$1, function() { - for (; i < _queue.length; i++) { - var callback = _queue[i]; - - do { - callback = callback(_isSync2); - } while (callback !== null); - } - }); - syncQueue = null; - } catch (error) { - // If something throws, leave the remaining callbacks on the queue. - if (syncQueue !== null) { - syncQueue = syncQueue.slice(i + 1); - } // Resume flushing in the next tick - - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ); - throw error; - } finally { - isFlushingSyncQueue = false; - } - } - } -} - -// TODO: this is special because it gets imported during build. -var ReactVersion = "17.0.1-454c2211c"; - -var NoMode = 0; -var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root -// tag instead - -var BlockingMode = 2; -var ConcurrentMode = 4; -var ProfileMode = 8; -var DebugTracingMode = 16; - -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; -var NoTransition = 0; -function requestCurrentTransition() { - return ReactCurrentBatchConfig.transition; -} - -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -function is(x, y) { - return ( - (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare - ); +/** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ +function is(x, y) { + return ( + (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare + ); } var objectIs = typeof Object.is === "function" ? Object.is : is; @@ -6205,7 +6279,7 @@ var ReactStrictModeWarnings = { var node = fiber; while (node !== null) { - if (node.mode & StrictMode) { + if (node.mode & StrictLegacyMode) { maybeStrictRoot = node; } @@ -6236,7 +6310,7 @@ var ReactStrictModeWarnings = { fiber, instance ) { - // Dedup strategy: Warn once per component. + // Dedupe strategy: Warn once per component. if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } @@ -6249,7 +6323,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function" ) { pendingUNSAFE_ComponentWillMountWarnings.push(fiber); @@ -6263,7 +6337,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); @@ -6277,7 +6351,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function" ) { pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); @@ -6595,9 +6669,7 @@ function exitDisallowedContextReadInDEV() { isDisallowedContextReadInDEV = false; } } -function pushProvider(providerFiber, nextValue) { - var context = providerFiber.type._context; - +function pushProvider(providerFiber, context, nextValue) { { push(valueCursor, context._currentValue, providerFiber); context._currentValue = nextValue; @@ -6618,10 +6690,9 @@ function pushProvider(providerFiber, nextValue) { } } } -function popProvider(providerFiber) { +function popProvider(context, providerFiber) { var currentValue = valueCursor.current; pop(valueCursor, providerFiber); - var context = providerFiber.type._context; { context._currentValue = currentValue; @@ -6708,16 +6779,31 @@ function propagateContextChange( // Match! Schedule an update on this fiber. if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate( - NoTimestamp, - pickArbitraryLane(renderLanes) - ); + var lane = pickArbitraryLane(renderLanes); + var update = createUpdate(NoTimestamp, lane); update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the // update to the current fiber, too, which means it will persist even if // this render is thrown away. Since it's a race condition, not sure it's // worth fixing. + // Inlined `enqueueUpdate` to remove interleaved update check + + var updateQueue = fiber.updateQueue; + + if (updateQueue === null); + else { + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - enqueueUpdate(fiber, update); + sharedQueue.pending = update; + } } fiber.lanes = mergeLanes(fiber.lanes, renderLanes); @@ -6852,6 +6938,48 @@ function readContext(context, observedBits) { return context._currentValue; } +// An array of all update queues that received updates during the current +// render. When this render exits, either because it finishes or because it is +// interrupted, the interleaved updates will be transfered onto the main part +// of the queue. +var interleavedQueues = null; +function pushInterleavedQueue(queue) { + if (interleavedQueues === null) { + interleavedQueues = [queue]; + } else { + interleavedQueues.push(queue); + } +} +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 + // point to the last node in a circular linked list. We need to append the + // interleaved list to the end of the pending list by joining them into a + // single, circular list. + if (interleavedQueues !== null) { + for (var i = 0; i < interleavedQueues.length; i++) { + var queue = interleavedQueues[i]; + var lastInterleavedUpdate = queue.interleaved; + + if (lastInterleavedUpdate !== null) { + queue.interleaved = null; + var firstInterleavedUpdate = lastInterleavedUpdate.next; + var lastPendingUpdate = queue.pending; + + if (lastPendingUpdate !== null) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = firstInterleavedUpdate; + lastInterleavedUpdate.next = firstPendingUpdate; + } + + queue.pending = lastInterleavedUpdate; + } + } + + interleavedQueues = null; + } +} + var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -6874,7 +7002,9 @@ function initializeUpdateQueue(fiber) { firstBaseUpdate: null, lastBaseUpdate: null, shared: { - pending: null + pending: null, + interleaved: null, + lanes: NoLanes }, effects: null }; @@ -6907,7 +7037,7 @@ function createUpdate(eventTime, lane) { }; return update; } -function enqueueUpdate(fiber, update) { +function enqueueUpdate(fiber, update, lane) { var updateQueue = fiber.updateQueue; if (updateQueue === null) { @@ -6916,17 +7046,35 @@ function enqueueUpdate(fiber, update) { } var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (isInterleavedUpdate(fiber)) { + var interleaved = sharedQueue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(sharedQueue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + sharedQueue.interleaved = update; } else { - update.next = pending.next; - pending.next = update; - } + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - sharedQueue.pending = update; + sharedQueue.pending = update; + } { if ( @@ -6944,6 +7092,33 @@ function enqueueUpdate(fiber, update) { } } } +function entangleTransitions(root, fiber, lane) { + var updateQueue = fiber.updateQueue; + + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; + } + + var sharedQueue = updateQueue.shared; + + if (isTransitionLane(lane)) { + var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must + // have finished. We can remove them from the shared queue, which represents + // a superset of the actually pending lanes. In some cases we may entangle + // more than we need to, but that's OK. In fact it's worse if we *don't* + // entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } +} function enqueueCapturedUpdate(workInProgress, capturedUpdate) { // Captured updates are updates that are thrown by a child during the render // phase. They should be discarded if the render is aborted. Therefore, @@ -7045,7 +7220,7 @@ function getStateFromUpdate( var nextState = payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7083,7 +7258,7 @@ function getStateFromUpdate( partialState = _payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7273,7 +7448,24 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { queue.baseState = newBaseState; queue.firstBaseUpdate = newFirstBaseUpdate; - queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. + queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.shared.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + newLanes = mergeLanes(newLanes, interleaved.lane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (firstBaseUpdate === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.shared.lanes = NoLanes; + } // Set the remaining expiration time to be whatever is remaining in the queue. // This should be fine because the only two other things that contribute to // expiration time are props and context. We're already in the middle of the // begin phase by the time we start processing the queue, so we've already @@ -7414,7 +7606,7 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7463,7 +7655,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); @@ -7482,7 +7678,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); @@ -7500,7 +7700,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } } }; @@ -7517,7 +7721,7 @@ function checkShouldComponentUpdate( if (typeof instance.shouldComponentUpdate === "function") { { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7853,7 +8057,7 @@ function constructClassInstance(workInProgress, ctor, props) { } // Instantiate twice to help detect side-effects. { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -8066,7 +8270,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -8110,7 +8314,9 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } } @@ -8172,7 +8378,9 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } return false; @@ -8218,13 +8426,17 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8474,7 +8686,7 @@ function coerceRef(returnFiber, current, element) { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant if ( - (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + (returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs // because these cannot be automatically converted to an arrow function // using a codemod. Therefore, we don't have to warn about string refs again. !( @@ -8576,12 +8788,14 @@ function coerceRef(returnFiber, current, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { + var childString = Object.prototype.toString.call(newChild); + { throw Error( "Objects are not valid as a React child (found: " + - (Object.prototype.toString.call(newChild) === "[object Object]" + (childString === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : childString) + "). If you meant to render a collection of children, use an array instead." ); } @@ -8604,7 +8818,7 @@ function warnOnFunctionType(returnFiber) { "Or maybe you meant to call this function rather than return it." ); } -} // 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. @@ -8614,23 +8828,16 @@ function ChildReconciler(shouldTrackSideEffects) { if (!shouldTrackSideEffects) { // Noop. return; - } // Deletions are added in reversed order so we add it to the front. - // At this point, the return fiber's effect list is empty except for - // deletions, so we can just append the deletion to the list. The remaining - // effects aren't added until the complete phase. Once we implement - // resuming, this may not be true. + } - var last = returnFiber.lastEffect; + var deletions = returnFiber.deletions; - if (last !== null) { - last.nextEffect = childToDelete; - returnFiber.lastEffect = childToDelete; + if (deletions === null) { + returnFiber.deletions = [childToDelete]; + returnFiber.flags |= ChildDeletion; } else { - returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + deletions.push(childToDelete); } - - childToDelete.nextEffect = null; - childToDelete.flags = Deletion; } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -8694,7 +8901,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (oldIndex < lastPlacedIndex) { // This is a move. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } else { // This item can stay in place. @@ -8702,7 +8909,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } else { // This is an insertion. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } } @@ -8711,7 +8918,7 @@ function ChildReconciler(shouldTrackSideEffects) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { - newFiber.flags = Placement; + newFiber.flags |= Placement; } return newFiber; @@ -8732,10 +8939,26 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current, element, lanes) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + } + if (current !== null) { if ( - current.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current, element) + current.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. + // 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 ) { // Move based on index var existing = useFiber(current, element.props); @@ -8874,16 +9097,6 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ); - } - return updateElement(returnFiber, oldFiber, newChild, lanes); } else { return null; @@ -8941,16 +9154,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key === null ? newIdx : newChild.key ) || null; - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - _matchedFiber, - newChild.props.children, - lanes, - newChild.key - ); - } - return updateElement(returnFiber, _matchedFiber, newChild, lanes); } @@ -9444,45 +9647,43 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - switch (child.tag) { - case Fragment: { - if (element.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, element.props.children); - existing.return = returnFiber; + var elementType = element.type; - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; - return existing; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - break; + return existing; } + } else { + if ( + child.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. + // 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 + ) { + deleteRemainingChildren(returnFiber, child.sibling); - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing = useFiber(child, element.props); - - _existing.ref = coerceRef(returnFiber, child, element); - _existing.return = returnFiber; + var _existing = useFiber(child, element.props); - { - _existing._debugSource = element._source; - _existing._debugOwner = element._owner; - } + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; - return _existing; + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; } - break; + return _existing; } } // Didn't match. @@ -9913,21 +10114,6 @@ function findFirstSuspended(row) { return null; } -var NoFlags$1 = - /* */ - 0; // Represents whether effect should fire. - -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ - 2; -var Passive$1 = - /* */ - 4; - var isHydrating = false; function enterHydrationState(fiber) { @@ -10023,6 +10209,12 @@ function warnAboutMultipleRenderersDEV(mutableSource) { } } // Eager reads the version of a mutable source and stores it on the root. +function getSuspendedCachePool() { + { + return null; + } // We check the cache on the stack first, since that's the one any new Caches +} + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; @@ -10308,7 +10500,20 @@ function renderWithHooks( { currentHookNameInDev = null; hookTypesDev = null; - hookTypesUpdateIndexDev = -1; + hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last + // render. If this fires, it suggests that we incorrectly reset the static + // flags in some other part of the codebase. This has happened before, for + // example, in the SuspenseList implementation. + + if ( + current !== null && + (current.flags & PassiveStatic) !== (workInProgress.flags & PassiveStatic) + ) { + error( + "Internal React error: Expected static flag was missing. Please " + + "notify the React team." + ); + } } didScheduleRenderPhaseUpdate = false; @@ -10322,8 +10527,13 @@ function renderWithHooks( return children; } function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; - workInProgress.flags &= ~(Passive | Update); + workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the + // complete phase (bubbleProperties). + + { + workInProgress.flags &= ~(Passive | Update); + } + current.lanes = removeLanes(current.lanes, lanes); } function resetHooksAfterThrow() { @@ -10474,6 +10684,8 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState @@ -10611,6 +10823,28 @@ function updateReducer(reducer, initialArg, init) { hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; + } // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + var interleavedLane = interleaved.lane; + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + interleavedLane + ); + markSkippedUpdateLanes(interleavedLane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (baseQueue === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.lanes = NoLanes; } var dispatch = queue.dispatch; @@ -10738,11 +10972,48 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { // // This can lead to tearing in the first renderer when it resumes, // but there's nothing we can do about that (short of throwing here and refusing to continue the render). - markSourceAsDirty(source); + markSourceAsDirty(source); // Intentioally throw an error to force React to retry synchronously. During + // the synchronous retry, it will block interleaved mutations, so we should + // get a consistent read. Therefore, the following error should never be + // visible to the user. + // + // If it were to become visible to the user, it suggests one of two things: + // a bug in React, or (more likely), a mutation during the render phase that + // caused the second re-render attempt to be different from the first. + // + // We know it's the second case if the logs are currently disabled. So in + // dev, we can present a more accurate error message. + + { + // eslint-disable-next-line react-internal/no-production-logging + if (console.log.__reactDisabledLog) { + // If the logs are disabled, this is the dev-only double render. This is + // only reachable if there was a mutation during render. Show a helpful + // error message. + // + // Something interesting to note: because we only double render in + // development, this error will never happen during production. This is + // actually true of all errors that occur during a double render, + // because if the first render had thrown, we would have exited the + // begin phase without double rendering. We should consider suppressing + // any error from a double render (with a warning) to more closely match + // the production behavior. + var componentName = getComponentName(currentlyRenderingFiber$1.type); + + { + throw Error( + "A mutable source was mutated while the " + + componentName + + " component was rendering. This is not supported. Move any mutations into event handlers or effects." + ); + } + } + } // We expect this error not to be thrown during the synchronous retry, + // because we blocked interleaved mutations. { throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } } @@ -10878,6 +11149,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { // including any interleaving updates that occur. var newQueue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -10925,6 +11198,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -11018,7 +11293,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); return; } } @@ -11041,7 +11316,9 @@ function mountEffect(create, deps) { } } - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + { + return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); + } } function updateEffect(create, deps) { @@ -11052,11 +11329,13 @@ function updateEffect(create, deps) { } } - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + return updateEffectImpl(Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + { + return mountEffectImpl(Update, Layout, create, deps); + } } function updateLayoutEffect(create, deps) { @@ -11108,12 +11387,15 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; - return mountEffectImpl( - Update, - Layout, - imperativeHandleEffect.bind(null, create, ref), - effectDeps - ); + + { + return mountEffectImpl( + Update, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); + } } function updateImperativeHandle(ref, create, deps) { @@ -11268,15 +11550,15 @@ function startTransition(setPending, callback) { { runWithPriority( - priorityLevel < UserBlockingPriority$1 - ? UserBlockingPriority$1 + priorityLevel < UserBlockingPriority + ? UserBlockingPriority : priorityLevel, function() { setPending(true); } ); runWithPriority( - priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, + priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function() { var prevTransition = ReactCurrentBatchConfig$1.transition; ReactCurrentBatchConfig$1.transition = 1; @@ -11388,19 +11670,7 @@ function dispatchAction(fiber, queue, action) { eagerReducer: null, eagerState: null, next: null - }; // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - queue.pending = update; + }; var alternate = fiber.alternate; if ( @@ -11411,7 +11681,47 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; } else { + if (isInterleavedUpdate(fiber)) { + var interleaved = queue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + queue.interleaved = update; + } else { + var _pending = queue.pending; + + if (_pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = _pending.next; + _pending.next = update; + } + + queue.pending = update; + } + if ( fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes) @@ -11464,7 +11774,24 @@ function dispatchAction(fiber, queue, action) { } } - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (isTransitionLane(lane) && root !== null) { + var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they + // must have finished. We can remove them from the shared queue, which + // represents a superset of the actually pending lanes. In some cases we + // may entangle more than we need to, but that's OK. In fact it's worse if + // we *don't* entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } } } @@ -11486,6 +11813,7 @@ var ContextOnlyDispatcher = { useOpaqueIdentifier: throwInvalidHookError, unstable_isNewReconciler: enableNewReconciler }; + var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; @@ -11615,6 +11943,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnMountWithHookTypesInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11712,6 +12041,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11809,6 +12139,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11906,6 +12237,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12018,6 +12350,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12130,6 +12463,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12172,218 +12506,621 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; var prevDispatcher = ReactCurrentDispatcher$1.current; ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(source, getSnapshot, subscribe); + }, + useOpaqueIdentifier: function() { + currentHookNameInDev = "useOpaqueIdentifier"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderOpaqueIdentifier(); + }, + unstable_isNewReconciler: enableNewReconciler + }; +} + +var now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; + +function getCommitTime() { + return commitTime; +} + +function recordCommitTime() { + commitTime = now$1(); +} + +function startProfilerTimer(fiber) { + profilerStartTime = now$1(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); + } +} + +function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} + +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } +} + +function transferActualDuration(fiber) { + // Transfer time spent rendering these children so we don't lose it + // after we rerender. This is used as a helper in special cases + // where we should count the work of multiple passes. + var child = fiber.child; + + while (child) { + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } +} + +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; + +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} + +function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + if (current === null) { + // If this is a fresh new component that hasn't been rendered yet, we + // won't update its child set by applying minimal side-effects. Instead, + // we will add them all to the child before it gets rendered. That means + // we can optimize this reconciliation pass by not tracking side-effects. + workInProgress.child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + // If the current child is the same as the work in progress, it means that + // we haven't yet started any work on these children. Therefore, we use + // the clone algorithm to create a copy of all the current children. + // If we had any progressed work already, that is invalid at this point so + // let's throw it out. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + nextChildren, + renderLanes + ); + } +} + +function forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes +) { + // This function is fork of reconcileChildren. It's used in cases where we + // want to reconcile without matching against the existing set. This has the + // effect of all current children being unmounted; even if the type and key + // are the same, the old child is unmounted and a new child is created. + // + // To do this, we're going to go through the reconcile algorithm twice. In + // the first pass, we schedule a deletion for all the current children by + // passing null. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + null, + renderLanes + ); // In the second pass, we mount the new children. The trick here is that we + // pass null in place of where we usually pass the current child set. This has + // the effect of remounting all children regardless of whether their + // identities match. + + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); +} + +function updateForwardRef( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; + + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) + ); + } + } + } + + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + } finally { + reenableLogs(); + } + } + + setIsRendering(false); + } + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateLanes, + renderLanes +) { + if (current === null) { + var type = Component.type; + + if ( + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined + ) { + var resolvedType = type; + + { + resolvedType = resolveFunctionForHotReloading(type); + } // If this is a plain function component without default props, + // and with only the default shallow comparison, we upgrade it + // to a SimpleMemoComponent to allow fast path updates. + + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + updateLanes, + renderLanes + ); + } + + { + var innerPropTypes = type.propTypes; + + if (innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(type) + ); + } + } + + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } + + { + var _type = Component.type; + var _innerPropTypes = _type.propTypes; + + if (_innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + _innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(_type) + ); + } + } + + var currentChild = current.child; // This is always exactly one child - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + if (!includesSomeLane(updateLanes, renderLanes)) { + // This will be the props with resolved defaultProps, + // unlike current.memoizedProps which will be the unresolved ones. + var prevProps = currentChild.memoizedProps; // Default to shallow comparison - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useDeferredValue: function(value) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value); - }, - useTransition: function() { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(); - }, - useMutableSource: function(source, getSnapshot, subscribe) { - currentHookNameInDev = "useMutableSource"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateMutableSource(source, getSnapshot, subscribe); - }, - useOpaqueIdentifier: function() { - currentHookNameInDev = "useOpaqueIdentifier"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderOpaqueIdentifier(); - }, - unstable_isNewReconciler: enableNewReconciler - }; -} + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; -var now$1 = Scheduler.unstable_now; -var commitTime = 0; -var profilerStartTime = -1; + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + } // React DevTools reads this flag. -function getCommitTime() { - return commitTime; + workInProgress.flags |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; } -function recordCommitTime() { - commitTime = now$1(); -} +function updateSimpleMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateLanes, + renderLanes +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens when the inner render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var outerMemoType = workInProgress.elementType; -function startProfilerTimer(fiber) { - profilerStartTime = now$1(); + if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { + // We warn when you define propTypes on lazy() + // so let's just skip over it to find memo() outer wrapper. + // Inner props for memo are validated later. + var lazyComponent = outerMemoType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; - if (fiber.actualStartTime < 0) { - fiber.actualStartTime = now$1(); + try { + outerMemoType = init(payload); + } catch (x) { + outerMemoType = null; + } // Inner propTypes will be validated in the function component path. + + var outerPropTypes = outerMemoType && outerMemoType.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentName(outerMemoType) + ); + } + } + } } -} -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; + if (current !== null) { + var prevProps = current.memoizedProps; + + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type + ) { + didReceiveUpdate = false; + + if (!includesSomeLane(renderLanes, updateLanes)) { + // The pending lanes were cleared at the beginning of beginWork. We're + // about to bail out, but there might be other lanes that weren't + // included in the current render. Usually, the priority level of the + // remaining updates is accumlated during the evaluation of the + // component (i.e. when processing the update queue). But since since + // we're bailing out early *without* evaluating the component, we need + // to account for it here, too. Reset to the value of the current fiber. + // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, + // because a MemoComponent fiber does not have hooks or an update queue; + // rather, it wraps around an inner component, which may or may not + // contains hooks. + // TODO: Move the reset at in beginWork out of the common path so that + // this is no longer necessary. + workInProgress.lanes = current.lanes; + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + } + } + } + + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); } -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var prevState = current !== null ? current.memoizedState : null; // If this is not null, this is a cache pool that was carried over from the + // previous render. We will push this to the cache pool context so that we can + // resume in-flight requests. - if (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; + var spawnedCachePool = null; + + if ( + nextProps.mode === "hidden" || + nextProps.mode === "unstable-defer-without-hiding" + ) { + // Rendering a hidden tree. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Figure out what we should do in Blocking mode. + var nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = nextState; + pushRenderLanes(workInProgress, renderLanes); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. + var nextBaseLanes; + + if (prevState !== null) { + var prevBaseLanes = prevState.baseLanes; + nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); + } else { + nextBaseLanes = renderLanes; + } // Schedule this fiber to re-render at offscreen priority. Then bailout. + + { + markSpawnedWork(OffscreenLane); + } + + workInProgress.lanes = workInProgress.childLanes = laneToLanes( + OffscreenLane + ); + var _nextState = { + baseLanes: nextBaseLanes, + cachePool: spawnedCachePool + }; + workInProgress.memoizedState = _nextState; + workInProgress.updateQueue = null; // We're about to bail out, but we need to push this to the stack anyway + // to avoid a push/pop misalignment. + + pushRenderLanes(workInProgress, nextBaseLanes); + return null; + } else { + var _nextState2 = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. + + var subtreeRenderLanes = + prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); + } + } else { + // Rendering a visible tree. + var _subtreeRenderLanes; + + if (prevState !== null) { + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); + + workInProgress.memoizedState = null; + } else { + // We weren't previously hidden, and we still aren't, so there's nothing + // special to do. Need to push to the stack regardless, though, to avoid + // a push/pop misalignment. + _subtreeRenderLanes = renderLanes; } - profilerStartTime = -1; + pushRenderLanes(workInProgress, _subtreeRenderLanes); } -} -function transferActualDuration(fiber) { - // Transfer time spent rendering these children so we don't lose it - // after we rerender. This is used as a helper in special cases - // where we should count the work of multiple passes. - var child = fiber.child; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} // Note: These happen to have identical begin phases, for now. We shouldn't hold +// ourselves to this constraint, though. If the behavior diverges, we should +// fork the function. - while (child) { - fiber.actualDuration += child.actualDuration; - child = child.sibling; - } -} +var updateLegacyHiddenComponent = updateOffscreenComponent; -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; -var didReceiveUpdate = false; -var didWarnAboutBadClass; -var didWarnAboutModulePatternComponent; -var didWarnAboutContextTypeOnFunctionComponent; -var didWarnAboutGetDerivedStateOnFunctionComponent; -var didWarnAboutFunctionRefs; -var didWarnAboutReassigningProps; -var didWarnAboutRevealOrder; -var didWarnAboutTailOptions; +function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; +function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { - if (current === null) { - // If this is a fresh new component that hasn't been rendered yet, we - // won't update its child set by applying minimal side-effects. Instead, - // we will add them all to the child before it gets rendered. That means - // we can optimize this reconciliation pass by not tracking side-effects. - workInProgress.child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - } else { - // If the current child is the same as the work in progress, it means that - // we haven't yet started any work on these children. Therefore, we use - // the clone algorithm to create a copy of all the current children. - // If we had any progressed work already, that is invalid at this point so - // let's throw it out. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); +function updateProfiler(current, workInProgress, renderLanes) { + { + workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; } + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes -) { - // This function is fork of reconcileChildren. It's used in cases where we - // want to reconcile without matching against the existing set. This has the - // effect of all current children being unmounted; even if the type and key - // are the same, the old child is unmounted and a new child is created. - // - // To do this, we're going to go through the reconcile algorithm twice. In - // the first pass, we schedule a deletion for all the current children by - // passing null. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ); // In the second pass, we mount the new children. The trick here is that we - // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their - // identities match. +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; + } } -function updateForwardRef( +function updateFunctionComponent( current, workInProgress, Component, nextProps, renderLanes ) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens after the first render suspends. - // We'll need to figure out if this is fine or can cause issues. { if (workInProgress.type !== workInProgress.elementType) { // Lazy component props can't be validated in createElement @@ -12401,8 +13138,12 @@ function updateForwardRef( } } - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + var context; + + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } var nextChildren; prepareToReadContext(workInProgress, renderLanes); @@ -12413,22 +13154,22 @@ function updateForwardRef( nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); } finally { @@ -12449,424 +13190,442 @@ function updateForwardRef( return workInProgress.child; } -function updateMemoComponent( +function updateClassComponent( current, workInProgress, Component, nextProps, - updateLanes, renderLanes ) { - if (current === null) { - var type = Component.type; - - if ( - isSimpleFunctionComponent(type) && - Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. - Component.defaultProps === undefined - ) { - var resolvedType = type; - - { - resolvedType = resolveFunctionForHotReloading(type); - } // If this is a plain function component without default props, - // and with only the default shallow comparison, we upgrade it - // to a SimpleMemoComponent to allow fast path updates. - - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; - - { - validateFunctionComponentInDev(workInProgress, type); - } - - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - renderLanes - ); - } - - { - var innerPropTypes = type.propTypes; + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; if (innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. checkPropTypes( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(type) + getComponentName(Component) ); } } + } // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; + var hasContext; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; - if (_innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. - checkPropTypes( - _innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(_type) - ); - } + 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. + + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + shouldUpdate = true; + } else if (current === null) { + // In a resume, we'll already have an instance we can reuse. + shouldUpdate = resumeMountClassInstance( + workInProgress, + Component, + nextProps, + renderLanes + ); + } else { + shouldUpdate = updateClassInstance( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); } - var currentChild = current.child; // This is always exactly one child + var nextUnitOfWork = finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ); - if (!includesSomeLane(updateLanes, renderLanes)) { - // This will be the props with resolved defaultProps, - // unlike current.memoizedProps which will be the unresolved ones. - var prevProps = currentChild.memoizedProps; // Default to shallow comparison + { + var inst = workInProgress.stateNode; - var compare = Component.compare; - compare = compare !== null ? compare : shallowEqual; + if (shouldUpdate && inst.props !== nextProps) { + if (!didWarnAboutReassigningProps) { + error( + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentName(workInProgress.type) || "a component" + ); + } - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didWarnAboutReassigningProps = true; } - } // React DevTools reads this flag. + } - workInProgress.flags |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); - newChild.ref = workInProgress.ref; - newChild.return = workInProgress; - workInProgress.child = newChild; - return newChild; + return nextUnitOfWork; } -function updateSimpleMemoComponent( +function finishClassComponent( current, workInProgress, Component, - nextProps, - updateLanes, + shouldUpdate, + hasContext, renderLanes ) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens when the inner render suspends. - // We'll need to figure out if this is fine or can cause issues. - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var outerMemoType = workInProgress.elementType; + // Refs should update even if shouldComponentUpdate returns false + markRef(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; - if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { - // We warn when you define propTypes on lazy() - // so let's just skip over it to find memo() outer wrapper. - // Inner props for memo are validated later. - var lazyComponent = outerMemoType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + if (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); + } - try { - outerMemoType = init(payload); - } catch (x) { - outerMemoType = null; - } // Inner propTypes will be validated in the function component path. + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } - var outerPropTypes = outerMemoType && outerMemoType.propTypes; + var instance = workInProgress.stateNode; // Rerender - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentName(outerMemoType) - ); + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; + + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; + + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); + + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + instance.render(); + } finally { + reenableLogs(); } } + + setIsRendering(false); } - } + } // React DevTools reads this flag. - if (current !== null) { - var prevProps = current.memoizedProps; + workInProgress.flags |= PerformedWork; - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type - ) { - didReceiveUpdate = false; + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. - if (!includesSomeLane(renderLanes, updateLanes)) { - // The pending lanes were cleared at the beginning of beginWork. We're - // about to bail out, but there might be other lanes that weren't - // included in the current render. Usually, the priority level of the - // remaining updates is accumlated during the evaluation of the - // component (i.e. when processing the update queue). But since since - // we're bailing out early *without* evaluating the component, we need - // to account for it here, too. Reset to the value of the current fiber. - // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, - // because a MemoComponent fiber does not have hooks or an update queue; - // rather, it wraps around an inner component, which may or may not - // contains hooks. - // TODO: Move the reset at in beginWork out of the common path so that - // this is no longer necessary. - workInProgress.lanes = current.lanes; - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } - } + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); + return workInProgress.child; } -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - var prevState = current !== null ? current.memoizedState : null; - - if ( - nextProps.mode === "hidden" || - nextProps.mode === "unstable-defer-without-hiding" - ) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy sync mode, don't defer the subtree. Render it now. - // TODO: Figure out what we should do in Blocking mode. - var nextState = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = nextState; - pushRenderLanes(workInProgress, renderLanes); - } else if (!includesSomeLane(renderLanes, OffscreenLane)) { - var nextBaseLanes; - - if (prevState !== null) { - var prevBaseLanes = prevState.baseLanes; - nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); - } else { - nextBaseLanes = renderLanes; - } // Schedule this fiber to re-render at offscreen priority. Then bailout. +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; - { - markSpawnedWork(OffscreenLane); - } + if (root.pendingContext) { + pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); + } - workInProgress.lanes = workInProgress.childLanes = laneToLanes( - OffscreenLane - ); - var _nextState = { - baseLanes: nextBaseLanes - }; - workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway - // to avoid a push/pop misalignment. + pushHostContainer(workInProgress, root.containerInfo); +} - pushRenderLanes(workInProgress, nextBaseLanes); - return null; - } else { - // Rendering at offscreen, so we can clear the base lanes. - var _nextState2 = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; - var subtreeRenderLanes = - prevState !== null ? prevState.baseLanes : renderLanes; - pushRenderLanes(workInProgress, subtreeRenderLanes); - } - } else { - var _subtreeRenderLanes; + if (!(current !== null && updateQueue !== null)) { + throw Error( + "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." + ); + } - if (prevState !== null) { - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState.element; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; + var root = workInProgress.stateNode; + // being called "element". - workInProgress.memoizedState = null; - } else { - // We weren't previously hidden, and we still aren't, so there's nothing - // special to do. Need to push to the stack regardless, though, to avoid - // a push/pop misalignment. - _subtreeRenderLanes = renderLanes; - } + var nextChildren = nextState.element; - pushRenderLanes(workInProgress, _subtreeRenderLanes); + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} // Note: These happen to have identical begin phases, for now. We shouldn't hold -// ourselves to this constraint, though. If the behavior diverges, we should -// fork the function. + if (root.hydrate && enterHydrationState()) { + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + workInProgress.child = child; + var node = child; -var updateLegacyHiddenComponent = updateOffscreenComponent; + while (node) { + // Mark each child 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. + node.flags = (node.flags & ~Placement) | Hydrating; + node = node.sibling; + } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } -function updateFragment(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function updateMode(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} +function updateHostComponent(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); -function updateProfiler(current, workInProgress, renderLanes) { - { - workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, + var type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + if (prevProps !== null && shouldSetTextContent()) { + // If we're switching from a direct text child to a normal child, or to + // empty, we need to schedule the text content to be reset. + workInProgress.flags |= ContentReset; } - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; + markRef(current, workInProgress); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef(current, workInProgress) { - var ref = workInProgress.ref; +function updateHostText(current, workInProgress) { + // immediately after. - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } + return null; } -function updateFunctionComponent( - current, +function mountLazyComponent( + _current, workInProgress, - Component, - nextProps, + elementType, + updateLanes, renderLanes ) { - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + 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 - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } + workInProgress.flags |= Placement; } - var context; + var props = workInProgress.pendingProps; + var lazyComponent = elementType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + var Component = init(payload); // Store the unwrapped component in the type. - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component + ); + } - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes - ); + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - if (workInProgress.mode & StrictMode) { - disableLogs(); + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component + ); + } - try { - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); - } finally { - reenableLogs(); } + + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; } - setIsRendering(false); + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component) + ); + } + } + } + + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateLanes, + renderLanes + ); + return child; + } } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. + var hint = ""; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } } -function updateClassComponent( - current, +function mountIncompleteClassComponent( + _current, workInProgress, Component, nextProps, renderLanes ) { - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + 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 - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } - } // Push context providers early to prevent context stack mismatches. + workInProgress.flags |= Placement; + } // 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. // During mounting we don't know the child context yet as the instance doesn't exist. // We will invalidate the child context in finishClassComponent() right after rendering. @@ -12880,2412 +13639,2644 @@ function updateClassComponent( } prepareToReadContext(workInProgress, renderLanes); - var instance = workInProgress.stateNode; - var shouldUpdate; + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); +} - 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 +function mountIndeterminateComponent( + _current, + workInProgress, + 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; - } // In the initial pass we might need to construct the instance. + workInProgress.flags |= Placement; + } - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - shouldUpdate = true; - } else if (current === null) { - // In a resume, we'll already have an instance we can reuse. - shouldUpdate = resumeMountClassInstance( - workInProgress, - Component, - nextProps, - renderLanes - ); - } else { - shouldUpdate = updateClassInstance( - current, + var props = workInProgress.pendingProps; + var context; + + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); + } + + prepareToReadContext(workInProgress, renderLanes); + var value; + + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName + ); + + didWarnAboutBadClass[componentName] = true; + } + } + + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } + + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, workInProgress, Component, - nextProps, + props, + context, renderLanes ); - } + setIsRendering(false); + } // React DevTools reads this flag. - var nextUnitOfWork = finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes - ); + workInProgress.flags |= PerformedWork; { - var inst = workInProgress.stateNode; + // Support for module components is deprecated and is removed behind a flag. + // Whether or not it would crash later, we want to show a good message in DEV first. + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + var _componentName = getComponentName(Component) || "Unknown"; - if (shouldUpdate && inst.props !== nextProps) { - if (!didWarnAboutReassigningProps) { + if (!didWarnAboutModulePatternComponent[_componentName]) { error( - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName, + _componentName, + _componentName ); - } - didWarnAboutReassigningProps = true; + didWarnAboutModulePatternComponent[_componentName] = true; + } } } - return nextUnitOfWork; -} + if ( + // Run these checks in production only if the flag is off. + // Eventually we'll delete this branch altogether. + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + { + var _componentName2 = getComponentName(Component) || "Unknown"; -function finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes -) { - // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); - var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; + if (!didWarnAboutModulePatternComponent[_componentName2]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName2, + _componentName2, + _componentName2 + ); - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - var instance = workInProgress.stateNode; // Rerender + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + var hasContext = false; - if ( - didCaptureError && - typeof Component.getDerivedStateFromError !== "function" - ) { - // If we captured an error, but getDerivedStateFromError is not defined, - // unmount all the children. componentDidCatch will schedule an update to - // re-render a fallback. This is temporary until we migrate everyone to - // the new API. - // TODO: Warn in a future release. - nextChildren = null; + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - { - stopProfilerTimerIfRunning(); + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + var getDerivedStateFromProps = Component.getDerivedStateFromProps; + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); } + + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); } else { - { - setIsRendering(true); - nextChildren = instance.render(); + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; - if (workInProgress.mode & StrictMode) { + { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { - instance.render(); + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); } finally { reenableLogs(); } } - - setIsRendering(false); } - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; - if (current !== null && didCaptureError) { - // If we're recovering from an error, reconcile without reusing any of - // the existing children. Conceptually, the normal children and the children - // that are shown on error are two different sets, so we shouldn't reuse - // normal children even if their identities match. - forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes - ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } // Memoize state using the values we just used to render. - // TODO: Restructure so we never read values from the instance. + reconcileChildren(null, workInProgress, value, renderLanes); - workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + { + validateFunctionComponentInDev(workInProgress, Component); + } - if (hasContext) { - invalidateContextProvider(workInProgress, Component, true); + return workInProgress.child; } - - return workInProgress.child; } -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; - - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, false); - } +function validateFunctionComponentInDev(workInProgress, Component) { + { + if (Component) { + if (Component.childContextTypes) { + error( + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ); + } + } - pushHostContainer(workInProgress, root.containerInfo); -} + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); -function updateHostRoot(current, workInProgress, renderLanes) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - if (!(current !== null && updateQueue !== null)) { - throw Error( - "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." - ); - } + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - var nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property - // being called "element". + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - var nextChildren = nextState.element; + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } + } - var root = workInProgress.stateNode; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentName(Component) || "Unknown"; - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 + ); - while (node) { - // Mark each child 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. - node.flags = (node.flags & ~Placement) | Hydrating; - node = node.sibling; + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } } - } else { - // Otherwise reset hydration state in case we aborted and resumed another - // root. - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } - - return workInProgress.child; -} -function updateHostComponent(current, workInProgress, renderLanes) { - pushHostContext(workInProgress); + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentName(Component) || "Unknown"; - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error( + "%s: Function components do not support contextType.", + _componentName4 + ); - if (prevProps !== null && shouldSetTextContent()) { - // If we're switching from a direct text child to a normal child, or to - // empty, we need to schedule the text content to be reset. - workInProgress.flags |= ContentReset; + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } + } } - - markRef(current, workInProgress); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; } -function updateHostText(current, workInProgress) { - // immediately after. +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; - return null; +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCachePool() + }; } -function mountLazyComponent( - _current, +function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; + + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool + }; +} // TODO: Probably should inline this back + +function shouldRemainOnFallback( + suspenseContext, + current, workInProgress, - elementType, - updateLanes, 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 + // If we're already showing a fallback, there are cases where we need to + // remain on that fallback regardless of whether the content has resolved. + // For example, SuspenseList coordinates when nested content appears. + if (current !== null) { + var suspenseState = current.memoizedState; - workInProgress.flags |= Placement; + if (suspenseState === null) { + // Currently showing content. Don't hide it, even if ForceSuspenseFallack + // is true. More precise name might be "ForceRemainSuspenseFallback". + // Note: This is a factoring smell. Can't remain on a fallback if there's + // no fallback to remain on. + return false; + } + } // Not currently showing content. Consult the Suspense context. + + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); +} + +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); +} + +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + + { + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; + } + } + + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + + if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + showFallback = true; + workInProgress.flags &= ~DidCapture; + } else { + // Attempting the main content + if (current === null || current.memoizedState !== null) { + // This is a new mount or this boundary is already showing a fallback state. + // Mark this subtree context as having at least one invisible parent that could + // handle the fallback state. + // Boundaries without fallbacks or should be avoided are not considered since + // they cannot handle preferred fallback states. + if ( + nextProps.fallback !== undefined && + nextProps.unstable_avoidThisFallback !== true + ) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext + ); + } + } } - var props = workInProgress.pendingProps; - var lazyComponent = elementType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; - var Component = init(payload); // Store the unwrapped component in the type. + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense + // boundary's children. This involves some custom reconcilation logic. Two + // main reasons this is so complicated. + // + // First, Legacy Mode has different semantics for backwards compatibility. The + // primary tree will commit in an inconsistent state, so when we do the + // second pass to render the fallback, we do some exceedingly, uh, clever + // hacks to make that not totally break. Like transferring effects and + // deletions from hidden tree. In Concurrent Mode, it's much simpler, + // because we bailout on the primary tree completely and leave it in its old + // state, no effects. Same as what we do for Offscreen (except that + // Offscreen doesn't have the first render pass). + // + // Second is hydration. During hydration, the Suspense fiber has a slightly + // different layout, where the child points to a dehydrated fragment, which + // contains the DOM rendered by the server. + // + // Third, even if you set all that aside, Suspense is like error boundaries in + // that we first we try to render one tree, and if that fails, we render again + // and switch to a different tree. Like a try/catch block. So we have to track + // which branch we're currently rendering. Ideally we would model this using + // a stack. - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; + if (current === null) { + // Initial mount + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined); - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component - ); - } + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; - child = updateFunctionComponent( - null, + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } - - child = updateClassComponent( - null, + var primaryChildFragment = workInProgress.child; + primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackFragment; + } else if (typeof nextProps.unstable_expectedLoadTime === "number") { + // This is a CPU-bound tree. Skip this tree and show a placeholder to + // unblock the surrounding content. Then immediately retry after the + // initial commit. + var _fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - - case ForwardRef: { - { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component - ); - } - child = updateForwardRef( - null, - workInProgress, - Component, - resolvedProps, + var _primaryChildFragment = workInProgress.child; + _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( renderLanes ); - return child; - } + workInProgress.memoizedState = SUSPENDED_MARKER; // 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. - case MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + workInProgress.lanes = SomeRetryLane; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentName(Component) - ); - } - } + { + markSpawnedWork(SomeRetryLane); } - child = updateMemoComponent( - null, + return _fallbackFragment; + } else { + return mountSuspensePrimaryChildren( workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, + nextPrimaryChildren, renderLanes ); - return child; - } - } - - var hint = ""; - - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. - - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint - ); - } -} - -function mountIncompleteClassComponent( - _current, - workInProgress, - Component, - 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. - - workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` - // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. - - var hasContext; - - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); } else { - hasContext = false; - } - - prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); -} - -function mountIndeterminateComponent( - _current, - workInProgress, - 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; - } - - var props = workInProgress.pendingProps; - var context; + // This is an update. + // If the current fiber has a SuspenseState, that means it's already showing + // a fallback. + var prevState = current.memoizedState; - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); - context = getMaskedContext(workInProgress, unmaskedContext); - } + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - prepareToReadContext(workInProgress, renderLanes); - var value; + var _fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren2, + _nextFallbackChildren2, + renderLanes + ); - { - if ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; + 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; - if (!didWarnAboutBadClass[componentName]) { - error( - "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + - "This is likely to cause errors. Change %s to extend React.Component instead.", - componentName, - componentName + var _primaryChildFragment4 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren3, + renderLanes ); - didWarnAboutBadClass[componentName] = true; + workInProgress.memoizedState = null; + return _primaryChildFragment4; } - } - - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } + } else { + // The current tree is not already showing a fallback. + if (showFallback) { + // Timed out. + var _nextFallbackChildren3 = nextProps.fallback; + var _nextPrimaryChildren4 = nextProps.children; - setIsRendering(true); - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - setIsRendering(false); - } // React DevTools reads this flag. + var _fallbackChildFragment2 = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren4, + _nextFallbackChildren3, + renderLanes + ); - workInProgress.flags |= PerformedWork; + 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. - { - // Support for module components is deprecated and is removed behind a flag. - // Whether or not it would crash later, we want to show a good message in DEV first. - if ( - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - var _componentName = getComponentName(Component) || "Unknown"; + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment2; + } else { + // Still haven't timed out. Continue rendering the children, like we + // normally do. + var _nextPrimaryChildren5 = nextProps.children; - if (!didWarnAboutModulePatternComponent[_componentName]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName, - _componentName, - _componentName + var _primaryChildFragment6 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren5, + renderLanes ); - didWarnAboutModulePatternComponent[_componentName] = true; + workInProgress.memoizedState = null; + return _primaryChildFragment6; } } } +} - if ( - // Run these checks in production only if the flag is off. - // Eventually we'll delete this branch altogether. - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - { - var _componentName2 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutModulePatternComponent[_componentName2]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName2, - _componentName2, - _componentName2 - ); - - didWarnAboutModulePatternComponent[_componentName2] = true; - } - } // Proceed under the assumption that this is a class instance - - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. - - var hasContext = false; +function mountSuspensePrimaryChildren( + workInProgress, + primaryChildren, + renderLanes +) { + var mode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + renderLanes, + null + ); + primaryChildFragment.return = workInProgress; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } +function mountSuspenseFallbackChildren( + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + var fallbackChildFragment; - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; + if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) { + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = 0; + primaryChildFragment.treeBaseDuration = 0; } - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null ); } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; - - { - if (workInProgress.mode & StrictMode) { - disableLogs(); + primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + NoLanes, + null + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } - try { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - } finally { - reenableLogs(); - } - } - } + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - reconcileChildren(null, workInProgress, value, renderLanes); +function createWorkInProgressOffscreenFiber(current, offscreenProps) { + // The props argument to `createWorkInProgress` is `any` typed, so we use this + // wrapper function to constrain it. + return createWorkInProgress(current, offscreenProps); +} +function updateSuspensePrimaryChildren( + current, + workInProgress, + primaryChildren, + renderLanes +) { + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, { - validateFunctionComponentInDev(workInProgress, Component); + mode: "visible", + children: primaryChildren } + ); - return workInProgress.child; + if ((workInProgress.mode & BlockingMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; } -} - -function validateFunctionComponentInDev(workInProgress, Component) { - { - if (Component) { - if (Component.childContextTypes) { - error( - "%s(...): childContextTypes cannot be defined on a function component.", - Component.displayName || Component.name || "Component" - ); - } - } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); + } + } - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; +function updateSuspenseFallbackChildren( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); - } - } + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was + // already cloned. In legacy mode, the only case where this isn't true is + // when DevTools forces us to display a fallback; we skip the first render + // pass entirely and go straight to rendering the fallback. (In Concurrent + // Mode, SuspenseList can also trigger this scenario, but this is a legacy- + // only codepath.) + workInProgress.child !== currentPrimaryChildFragment + ) { + var progressedPrimaryFragment = workInProgress.child; + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentName(Component) || "Unknown"; + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = + 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. - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 - ); + workInProgress.deletions = null; + } else { + primaryChildFragment = createWorkInProgressOffscreenFiber( + 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.) - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } - } + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName4 = getComponentName(Component) || "Unknown"; + var fallbackChildFragment; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { - error( - "%s: Function components do not support contextType.", - _componentName4 - ); + if (currentFallbackChildFragment !== null) { + fallbackChildFragment = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + ); + } else { + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; - } - } + fallbackChildFragment.flags |= Placement; } + + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; } -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes - }; -} + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } -function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { - return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) - }; -} // TODO: Probably should inline this back + scheduleWorkOnParentPath(fiber.return, renderLanes); +} -function shouldRemainOnFallback( - suspenseContext, - current, +function propagateSuspenseContextChange( workInProgress, + firstChild, renderLanes ) { - // If we're already showing a fallback, there are cases where we need to - // remain on that fallback regardless of whether the content has resolved. - // For example, SuspenseList coordinates when nested content appears. - if (current !== null) { - var suspenseState = current.memoizedState; - - if (suspenseState === null) { - // Currently showing content. Don't hide it, even if ForceSuspenseFallack - // is true. More precise name might be "ForceRemainSuspenseFallback". - // Note: This is a factoring smell. Can't remain on a fallback if there's - // no fallback to remain on. - return false; - } - } // Not currently showing content. Consult the Suspense context. - - return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); -} - -function getRemainingWorkInPrimaryTree(current, renderLanes) { - // TODO: Should not remove render lanes that were pinged during this render - return removeLanes(current.childLanes, renderLanes); -} + // Mark any Suspense boundaries with fallbacks as having work to do. + // If they were previously forced into fallbacks, they may now be able + // to unblock. + var node = firstChild; -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - { - if (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; + if (state !== null) { + scheduleWorkOnFiber(node, renderLanes); + } + } else if (node.tag === SuspenseListComponent) { + // If the tail is hidden there might not be an Suspense boundaries + // to schedule work on. In this case we have to schedule it on the + // list itself. + // We don't have to traverse to the children of the list since + // the list will propagate the change when it rerenders. + scheduleWorkOnFiber(node, renderLanes); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - } - var suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + if (node === workInProgress) { + return; + } - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { - // Something in this boundary's subtree already suspended. Switch to - // rendering the fallback children. - showFallback = true; - workInProgress.flags &= ~DidCapture; - } else { - // Attempting the main content - if (current === null || current.memoizedState !== null) { - // This is a new mount or this boundary is already showing a fallback state. - // Mark this subtree context as having at least one invisible parent that could - // handle the fallback state. - // Boundaries without fallbacks or should be avoided are not considered since - // they cannot handle preferred fallback states. - if ( - nextProps.fallback !== undefined && - nextProps.unstable_avoidThisFallback !== true - ) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext - ); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } + + node = node.return; } + + node.sibling.return = node.return; + node = node.sibling; } +} - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense - // boundary's children. This involves some custom reconcilation logic. Two - // main reasons this is so complicated. - // - // First, Legacy Mode has different semantics for backwards compatibility. The - // primary tree will commit in an inconsistent state, so when we do the - // second pass to render the fallback, we do some exceedingly, uh, clever - // hacks to make that not totally break. Like transferring effects and - // deletions from hidden tree. In Concurrent Mode, it's much simpler, - // because we bailout on the primary tree completely and leave it in its old - // state, no effects. Same as what we do for Offscreen (except that - // Offscreen doesn't have the first render pass). - // - // Second is hydration. During hydration, the Suspense fiber has a slightly - // different layout, where the child points to a dehydrated fragment, which - // contains the DOM rendered by the server. - // - // Third, even if you set all that aside, Suspense is like error boundaries in - // that we first we try to render one tree, and if that fails, we render again - // and switch to a different tree. Like a try/catch block. So we have to track - // which branch we're currently rendering. Ideally we would model this using - // a stack. +function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; - if (current === null) { - // Initial mount - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; + } - if (showFallback) { - var fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); - var primaryChildFragment = workInProgress.child; - primaryChildFragment.memoizedState = mountSuspenseOffscreenState( - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return fallbackFragment; - } else if (typeof nextProps.unstable_expectedLoadTime === "number") { - // This is a CPU-bound tree. Skip this tree and show a placeholder to - // unblock the surrounding content. Then immediately retry after the - // initial commit. - var _fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); + row = row.sibling; + } - var _primaryChildFragment = workInProgress.child; - _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; // 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. + return lastContentRow; +} - workInProgress.lanes = SomeRetryLane; +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; - { - markSpawnedWork(SomeRetryLane); - } + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - return _fallbackFragment; - } else { - return mountSuspensePrimaryChildren( - workInProgress, - nextPrimaryChildren, - renderLanes - ); - } - } else { - // This is an update. - // If the current fiber has a SuspenseState, that means it's already showing - // a fallback. - var prevState = current.memoizedState; + break; + } - if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; + case "forward": + case "backward": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - var _fallbackChildFragment = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, - renderLanes - ); + break; + } - 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; + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + + break; + } } else { - var _nextPrimaryChildren3 = nextProps.children; + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } + } + } +} - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; + + error( + '"%s" is not a supported value for tail on . ' + + 'Did you mean "collapsed" or "hidden"?', + tailMode ); + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; - workInProgress.memoizedState = null; - return _primaryChildFragment4; + error( + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); } - } else { - // The current tree is not already showing a fallback. - if (showFallback) { - // Timed out. - var _nextFallbackChildren3 = nextProps.fallback; - var _nextPrimaryChildren4 = nextProps.children; + } + } +} - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes - ); +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; - 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. + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); + + return false; + } + } - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment2; + return true; +} + +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (Array.isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; + } + } } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - var _nextPrimaryChildren5 = nextProps.children; + var iteratorFn = getIteratorFn(children); - var _primaryChildFragment6 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren5, - renderLanes - ); + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - workInProgress.memoizedState = null; - return _primaryChildFragment6; + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + + _i++; + } + } + } else { + error( + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); + } } } } } -function mountSuspensePrimaryChildren( - workInProgress, - primaryChildren, - renderLanes -) { - var mode = workInProgress.mode; - var primaryChildProps = { - mode: "visible", - children: primaryChildren - }; - var primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - renderLanes, - null - ); - primaryChildFragment.return = workInProgress; - workInProgress.child = primaryChildFragment; - return primaryChildFragment; -} - -function mountSuspenseFallbackChildren( +function initSuspenseListRenderState( workInProgress, - primaryChildren, - fallbackChildren, - renderLanes + isBackwards, + tail, + lastContentRow, + tailMode ) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; + var renderState = workInProgress.memoizedState; - if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) { - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.renderingStartTime = 0; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailMode = tailMode; + } +} // This can end up rendering this component multiple passes. +// The first pass splits the children fibers into two sets. A head and tail. +// We first render the head. If anything is in fallback state, we do another +// pass through beginWork to rerender all children (including the tail) with +// the force suspend context. If the first render didn't have anything in +// in fallback state. Then we render each row in the tail one-by-one. +// That happens in the completeWork phase without going back to beginWork. - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = 0; - primaryChildFragment.treeBaseDuration = 0; - } +function updateSuspenseListComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var revealOrder = nextProps.revealOrder; + var tailMode = nextProps.tail; + var newChildren = nextProps.children; + validateRevealOrder(revealOrder); + validateTailOptions(tailMode, revealOrder); + validateSuspenseListChildren(newChildren, revealOrder); + reconcileChildren(current, workInProgress, newChildren, renderLanes); + var suspenseContext = suspenseStackCursor.current; + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback ); + workInProgress.flags |= DidCapture; } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null - ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags; + + if (didSuspendBefore) { + // If we previously forced a fallback, we need to schedule work + // on any nested boundaries to let them know to try to render + // again. This is the same as context updating. + propagateSuspenseContextChange( + workInProgress, + workInProgress.child, + renderLanes + ); + } + + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - primaryChildFragment.return = workInProgress; - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; -} + pushSuspenseContext(workInProgress, suspenseContext); -function createWorkInProgressOffscreenFiber(current, offscreenProps) { - // The props argument to `createWorkInProgress` is `any` typed, so we use this - // wrapper function to constrain it. - return createWorkInProgress(current, offscreenProps); -} + if ((workInProgress.mode & BlockingMode) === NoMode) { + // In legacy mode, SuspenseList doesn't work so we just + // use make it a noop by treating it as the default revealOrder. + workInProgress.memoizedState = null; + } else { + switch (revealOrder) { + case "forwards": { + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; + + if (lastContentRow === null) { + // The whole list is part of the tail. + // TODO: We could fast path by just rendering the tail now. + tail = workInProgress.child; + workInProgress.child = null; + } else { + // Disconnect the tail rows after the content row. + // We're going to render them separately later. + tail = lastContentRow.sibling; + lastContentRow.sibling = null; + } + + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + tail, + lastContentRow, + tailMode + ); + break; + } + + case "backwards": { + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; + + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } + + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode + ); + break; + } -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - { - mode: "visible", - children: primaryChildren - } - ); + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined + ); + break; + } - if ((workInProgress.mode & BlockingMode) === NoMode) { - primaryChildFragment.lanes = renderLanes; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } + } } - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = null; + return workInProgress.child; +} - if (currentFallbackChildFragment !== null) { - // Delete the fallback child fragment - currentFallbackChildFragment.nextEffect = null; - currentFallbackChildFragment.flags = Deletion; - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + + if (current === null) { + // Portals are special because we don't append the children during mount + // but at commit. Therefore we need to track insertions which the normal + // flow doesn't do during mount. This doesn't happen at the root because + // the root always starts with a "current" with a null child. + // TODO: Consider unifying this with how the root works. + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); } - workInProgress.child = primaryChildFragment; - return primaryChildFragment; + return workInProgress.child; } -function updateSuspenseFallbackChildren( - current, - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - - if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was - // already cloned. In legacy mode, the only case where this isn't true is - // when DevTools forces us to display a fallback; we skip the first render - // pass entirely and go straight to rendering the fallback. (In Concurrent - // Mode, SuspenseList can also trigger this scenario, but this is a legacy- - // only codepath.) - workInProgress.child !== currentPrimaryChildFragment - ) { - var progressedPrimaryFragment = workInProgress.child; - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; +var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration; - primaryChildFragment.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration; - } // The fallback fiber was added as a deletion effect during the first pass. - // However, since we're going to remain on the fallback, we no longer want - // to delete it. So we need to remove it from the list. Deletions are stored - // on the same list as effects. We want to keep the effects from the primary - // tree. So we copy the primary child fragment's effect list, which does not - // include the fallback deletion effect. +function updateContextProvider(current, workInProgress, renderLanes) { + var providerType = workInProgress.type; + var context = providerType._context; + var newProps = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + var newValue = newProps.value; - var progressedLastEffect = primaryChildFragment.lastEffect; + { + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; - if (progressedLastEffect !== null) { - workInProgress.firstEffect = primaryChildFragment.firstEffect; - workInProgress.lastEffect = progressedLastEffect; - progressedLastEffect.nextEffect = null; - } else { - // TODO: Reset this somewhere else? Lol legacy mode is so weird. - workInProgress.firstEffect = workInProgress.lastEffect = null; + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + ); + } } - } else { - primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - primaryChildProps - ); - } - - var fallbackChildFragment; - if (currentFallbackChildFragment !== null) { - fallbackChildFragment = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - ); - } else { - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); // Needs a placement effect because the parent (the Suspense boundary) already - // mounted but this is a new fiber. + var providerPropTypes = workInProgress.type.propTypes; - fallbackChildFragment.flags |= Placement; + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + } } - fallbackChildFragment.return = workInProgress; - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; -} + pushProvider(workInProgress, context, newValue); -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; + if (oldProps !== null) { + var oldValue = oldProps.value; + var changedBits = calculateChangedBits(context, newValue, oldValue); - if (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + if (changedBits === 0) { + // No change. Bailout early if children are the same. + if (oldProps.children === newProps.children && !hasContextChanged()) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + } else { + // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange(workInProgress, context, changedBits, renderLanes); + } } - scheduleWorkOnParentPath(fiber.return, renderLanes); + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; } -function propagateSuspenseContextChange( - workInProgress, - firstChild, - renderLanes -) { - // Mark any Suspense boundaries with fallbacks as having work to do. - // If they were previously forced into fallbacks, they may now be able - // to unblock. - var node = firstChild; +var hasWarnedAboutUsingContextAsConsumer = false; - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; +function updateContextConsumer(current, workInProgress, renderLanes) { + var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In + // DEV mode, we create a separate object for Context.Consumer that acts + // like a proxy to Context. This proxy object adds unnecessary code in PROD + // so we use the old behaviour (Context.Consumer references Context) to + // reduce size and overhead. The separate object references context via + // a property called "_context", which also gives us the ability to check + // in DEV mode if this property exists or not and warn if it does not. - if (state !== null) { - scheduleWorkOnFiber(node, renderLanes); + { + if (context._context === undefined) { + // This may be because it's a Context (rather than a Consumer). + // Or it may be because it's older React where they're the same thing. + // We only want to warn if we're sure it's a new React. + if (context !== context.Consumer) { + if (!hasWarnedAboutUsingContextAsConsumer) { + hasWarnedAboutUsingContextAsConsumer = true; + + error( + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); + } } - } else if (node.tag === SuspenseListComponent) { - // If the tail is hidden there might not be an Suspense boundaries - // to schedule work on. In this case we have to schedule it on the - // list itself. - // We don't have to traverse to the children of the list since - // the list will propagate the change when it rerenders. - scheduleWorkOnFiber(node, renderLanes); - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; + } else { + context = context._context; } + } - if (node === workInProgress) { - return; + var newProps = workInProgress.pendingProps; + var render = newProps.children; + + { + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); } + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; + + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. - node = node.return; - } + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - node.sibling.return = node.return; - node = node.sibling; - } +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; } -function findLastContentRow(firstChild) { - // This is going to find the last row among these children that is already - // showing content on the screen, as opposed to being in fallback state or - // new. If a row has multiple Suspense boundaries, any of them being in the - // fallback state, counts as the whole row being in a fallback state. - // Note that the "rows" will be workInProgress, but any nested children - // will still be current since we haven't rendered them yet. The mounted - // order may not be the same as the new order. We use the new order. - var row = firstChild; - var lastContentRow = null; +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; - } + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. - row = row.sibling; + if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { + // The children don't have any work either. We can skip them. + // TODO: Once we add back resuming, we should check if the children are + // a work-in-progress set. If so, we need to transfer their effects. + return null; + } else { + // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. + cloneChildFibers(current, workInProgress); + return workInProgress.child; } - - return lastContentRow; } -function validateRevealOrder(revealOrder) { +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; + var returnFiber = oldWorkInProgress.return; - if (typeof revealOrder === "string") { - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'Use lowercase "%s" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - break; - } + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - case "forward": - case "backward": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'React uses the -s suffix in the spelling. Use "%ss" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - break; - } + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } - break; + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); } - } else { - error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); } - } - } -} -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. - error( - '"%s" is not a supported value for tail on . ' + - 'Did you mean "collapsed" or "hidden"?', - tailMode - ); - } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { - didWarnAboutTailOptions[tailMode] = true; + var deletions = returnFiber.deletions; - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode - ); - } + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(current); } + + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + + return newWorkInProgress; } } -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; - - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; +function beginWork(current, workInProgress, renderLanes) { + var updateLanes = workInProgress.lanes; - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type + { + if (workInProgress._debugNeedsRemount && current !== null) { + // This will restart the begin phase with a new fiber. + return remountFiber( + current, + workInProgress, + createFiberFromTypeAndProps( + workInProgress.type, + workInProgress.key, + workInProgress.pendingProps, + workInProgress._debugOwner || null, + workInProgress.mode, + workInProgress.lanes + ) ); - - return false; } } - return true; -} + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; -function validateSuspenseListChildren(children, revealOrder) { - { if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type ) { - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - if (!validateSuspenseListNestedChild(children[i], i)) { - return; + // If props or context changed, mark the fiber as having performed work. + // This may be unset if the props are determined to be equal later (memo). + didReceiveUpdate = true; + } else if (!includesSomeLane(renderLanes, updateLanes)) { + didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering + // the begin phase. There's still some bookkeeping we that needs to be done + // in this optimized path, mostly pushing stuff onto the stack. + + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; + + case HostComponent: + pushHostContext(workInProgress); + break; + + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); } + + break; } - } else { - var iteratorFn = getIteratorFn(children); - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; + + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + pushProvider(workInProgress, context, newValue); + break; + } + + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + if (hasChildWork) { + workInProgress.flags |= Update; + } // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } + + break; - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + case SuspenseComponent: { + var state = workInProgress.memoizedState; - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + if (state !== null) { + // 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. - _i++; + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; + + if (includesSomeLane(renderLanes, primaryChildLanes)) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + } else { + // The primary child fragment does not have pending work marked + // on it + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. + + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + return null; + } } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } - } else { - error( - 'A single row was passed to a . ' + - "This is not useful since it needs multiple rows. " + - "Did you mean to pass multiple children or an array?", - revealOrder - ); - } - } - } - } -} -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - var renderState = workInProgress.memoizedState; + break; + } - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering - }; - } else { - // We can reuse the existing object from previous renders. - renderState.isBackwards = isBackwards; - renderState.rendering = null; - renderState.renderingStartTime = 0; - renderState.last = lastContentRow; - renderState.tail = tail; - renderState.tailMode = tailMode; - renderState.lastEffect = lastEffectBeforeRendering; - } -} // This can end up rendering this component multiple passes. -// The first pass splits the children fibers into two sets. A head and tail. -// We first render the head. If anything is in fallback state, we do another -// pass through beginWork to rerender all children (including the tail) with -// the force suspend context. If the first render didn't have anything in -// in fallback state. Then we render each row in the tail one-by-one. -// That happens in the completeWork phase without going back to beginWork. + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; -function updateSuspenseListComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var revealOrder = nextProps.revealOrder; - var tailMode = nextProps.tail; - var newChildren = nextProps.children; - validateRevealOrder(revealOrder); - validateTailOptions(tailMode, revealOrder); - validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren(current, workInProgress, newChildren, renderLanes); - var suspenseContext = suspenseStackCursor.current; - var shouldForceFallback = hasSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - if (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.flags |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.flags & DidCapture) !== NoFlags; + if (didSuspendBefore) { + if (_hasChildWork) { + // If something was in fallback state last time, and we have all the + // same children then we're still in progressive loading state. + // Something might get unblocked by state updates or retries in the + // tree which will affect the tail. So we need to use the normal + // path to compute the correct tail. + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. - if (didSuspendBefore) { - // If we previously forced a fallback, we need to schedule work - // on any nested boundaries to let them know to try to render - // again. This is the same as context updating. - propagateSuspenseContextChange( - workInProgress, - workInProgress.child, - renderLanes - ); - } + workInProgress.flags |= DidCapture; + } // If nothing suspended before and we're rendering the same children, + // then the tail doesn't matter. Anything new that suspends will work + // in the "together" mode, so we can continue from the state we had. - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + var renderState = workInProgress.memoizedState; - pushSuspenseContext(workInProgress, suspenseContext); + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + renderState.lastEffect = null; + } - if ((workInProgress.mode & BlockingMode) === NoMode) { - // In legacy mode, SuspenseList doesn't work so we just - // use make it a noop by treating it as the default revealOrder. - workInProgress.memoizedState = null; - } else { - switch (revealOrder) { - case "forwards": { - var lastContentRow = findLastContentRow(workInProgress.child); - var tail; + pushSuspenseContext(workInProgress, suspenseStackCursor.current); - if (lastContentRow === null) { - // The whole list is part of the tail. - // TODO: We could fast path by just rendering the tail now. - tail = workInProgress.child; - workInProgress.child = null; - } else { - // Disconnect the tail rows after the content row. - // We're going to render them separately later. - tail = lastContentRow.sibling; - lastContentRow.sibling = null; + if (_hasChildWork) { + break; + } else { + // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + return null; + } } - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode, - workInProgress.lastEffect - ); - break; + case OffscreenComponent: + case LegacyHiddenComponent: { + // Need to check if the tree still needs to be deferred. This is + // almost identical to the logic used in the normal update path, + // so we'll just enter that. The only difference is we'll bail out + // at the next level instead of this one, because the child props + // have not changed. Which is fine. + // TODO: Probably should refactor `beginWork` to split the bailout + // path from the normal path. I'm tempted to do a labeled break here + // but I won't :) + workInProgress.lanes = NoLanes; + return updateOffscreenComponent(current, workInProgress, renderLanes); + } } - case "backwards": { - // We're going to find the first row that has existing content. - // At the same time we're going to reverse the list of everything - // we pass in the meantime. That's going to be our tail in reverse - // order. - var _tail = null; - var row = workInProgress.child; - workInProgress.child = null; - - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. - - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } else { + if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + } else { + // An update was scheduled on this fiber, but there are no new props + // nor legacy context. Set this to false. If an update queue or context + // consumer produces a changed value, it will set this to true. Otherwise, + // the component will assume the children have not changed and bail out. + didReceiveUpdate = false; + } + } + } else { + didReceiveUpdate = false; + } // Before entering the begin phase, clear pending update priority. + // TODO: This assumes that we're about to evaluate the component and process + // the update queue. However, there's an exception: SimpleMemoComponent + // sometimes bails out later in the begin phase. This indicates that we should + // move this assignment out of the common path and into each branch. - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + workInProgress.lanes = NoLanes; - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect - ); - break; - } + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect - ); - break; - } + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateLanes, + renderLanes + ); + } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; - } + case FunctionComponent: { + var _Component = workInProgress.type; + var unresolvedProps = workInProgress.pendingProps; + var resolvedProps = + workInProgress.elementType === _Component + ? unresolvedProps + : resolveDefaultProps(_Component, unresolvedProps); + return updateFunctionComponent( + current, + workInProgress, + _Component, + resolvedProps, + renderLanes + ); } - } - return workInProgress.child; -} + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - if (current === null) { - // Portals are special because we don't append the children during mount - // but at commit. Therefore we need to track insertions which the normal - // flow doesn't do during mount. This doesn't happen at the root because - // the root always starts with a "current" with a null child. - // TODO: Consider unifying this with how the root works. - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderLanes + ); + } - return workInProgress.child; -} + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); -var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + case HostComponent: + return updateHostComponent(current, workInProgress, renderLanes); -function updateContextProvider(current, workInProgress, renderLanes) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; + case HostText: + return updateHostText(); - { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); - error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - ); - } - } + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); - var providerPropTypes = workInProgress.type.propTypes; + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); + + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); } - } - pushProvider(workInProgress, newValue); + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + case Mode: + return updateMode(current, workInProgress, renderLanes); - if (changedBits === 0) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange(workInProgress, context, changedBits, renderLanes); - } - } + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); -var hasWarnedAboutUsingContextAsConsumer = false; + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); -function updateContextConsumer(current, workInProgress, renderLanes) { - var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In - // DEV mode, we create a separate object for Context.Consumer that acts - // like a proxy to Context. This proxy object adds unnecessary code in PROD - // so we use the old behaviour (Context.Consumer references Context) to - // reduce size and overhead. The separate object references context via - // a property called "_context", which also gives us the ability to check - // in DEV mode if this property exists or not and warn if it does not. + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - { - if (context._context === undefined) { - // This may be because it's a Context (rather than a Consumer). - // Or it may be because it's older React where they're the same thing. - // We only want to warn if we're sure it's a new React. - if (context !== context.Consumer) { - if (!hasWarnedAboutUsingContextAsConsumer) { - hasWarnedAboutUsingContextAsConsumer = true; + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) + ); + } } } - } else { - context = context._context; + + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateLanes, + renderLanes + ); } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateLanes, + renderLanes + ); + } - { - if (typeof render !== "function") { - error( - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; + + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); + + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderLanes ); } - } - - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. + case SuspenseListComponent: { + return updateSuspenseListComponent(current, workInProgress, renderLanes); + } - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + case ScopeComponent: { + break; + } -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} + case OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); + } -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; + case LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + } } { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } +} - markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; +} - if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { - // The children don't have any work either. We can skip them. - // TODO: Once we add back resuming, we should check if the children are - // a work-in-progress set. If so, we need to transfer their effects. - return null; - } else { - // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - cloneChildFibers(current, workInProgress); - return workInProgress.child; - } +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; } -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. +{ + // 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; - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + 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; + } - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + if (node === workInProgress) { + return; + } - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); + node = node.return; } - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + node.sibling.return = node.return; + node = node.sibling; + } + }; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); - } - } + updateHostContainer = function(current, workInProgress) { + // Noop + }; - prevSibling.sibling = newWorkInProgress; - } // Delete the old fiber and place the new one. - // Since the old fiber is disconnected, we have to schedule it manually. + 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; - var last = returnFiber.lastEffect; + 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. - if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; - } + 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`. - current.nextEffect = null; - current.flags = Deletion; - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. - return newWorkInProgress; - } -} + 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. -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; + if (updatePayload) { + markUpdate(workInProgress); + } + }; - { - if (workInProgress._debugNeedsRemount && current !== null) { - // This will restart the begin phase with a new fiber. - return remountFiber( - current, - workInProgress, - createFiberFromTypeAndProps( - workInProgress.type, - workInProgress.key, - workInProgress.pendingProps, - workInProgress._debugOwner || null, - workInProgress.mode, - workInProgress.lanes - ) - ); + 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); } - } + }; +} - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; +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; - if ( - oldProps !== newProps || - hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: - workInProgress.type !== current.type - ) { - // If props or context changed, mark the fiber as having performed work. - // This may be unset if the props are determined to be equal later (memo). - didReceiveUpdate = true; - } else if (!includesSomeLane(renderLanes, updateLanes)) { - didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering - // the begin phase. There's still some bookkeeping we that needs to be done - // in this optimized path, mostly pushing stuff onto the stack. + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - case HostComponent: - pushHostContext(workInProgress); - break; + 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; + } - case ClassComponent: { - var Component = workInProgress.type; + 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; + } - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - break; + 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; + } - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; + break; + } + } +} - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; - } +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + 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; - if (hasChildWork) { - workInProgress.flags |= Update; - } // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, + 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. - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } - break; + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; - case SuspenseComponent: { - var state = workInProgress.memoizedState; + 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. - if (state !== null) { - // 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. + _child.return = completedWork; + _child = _child.sibling; + } + } - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; + 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; - if (includesSomeLane(renderLanes, primaryChildLanes)) { - // The primary children have pending work. Use the normal path - // to attempt to render the primary children again. - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - } else { - // The primary child fragment does not have pending work marked - // on it - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); // The primary children do not have pending work with sufficient - // priority. Bailout. + 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. - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + 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. - if (child !== null) { - // The fallback children have pending work. Skip over the - // primary children and work on the fallback. - return child.sibling; - } else { - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); - } + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } - break; - } + completedWork.subtreeFlags |= subtreeFlags; + } - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} - var _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; - if (didSuspendBefore) { - if (_hasChildWork) { - // If something was in fallback state last time, and we have all the - // same children then we're still in progressive loading state. - // Something might get unblocked by state updates or retries in the - // tree which will affect the tail. So we need to use the normal - // path to compute the correct tail. - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - } // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. + 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; - workInProgress.flags |= DidCapture; - } // If nothing suspended before and we're rendering the same children, - // then the tail doesn't matter. Anything new that suspends will work - // in the "together" mode, so we can continue from the state we had. + case ClassComponent: { + var Component = workInProgress.type; - var renderState = workInProgress.memoizedState; + if (isContextProvider(Component)) { + popContext(workInProgress); + } - if (renderState !== null) { - // Reset to the "together" mode in case we've started a different - // update in the past but didn't complete it. - renderState.rendering = null; - renderState.tail = null; - renderState.lastEffect = null; - } + bubbleProperties(workInProgress); + return null; + } - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + case HostRoot: { + var fiberRoot = workInProgress.stateNode; - if (_hasChildWork) { - break; - } else { - // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. - return null; - } - } + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); - case OffscreenComponent: - case LegacyHiddenComponent: { - // Need to check if the tree still needs to be deferred. This is - // almost identical to the logic used in the normal update path, - // so we'll just enter that. The only difference is we'll bail out - // at the next level instead of this one, because the child props - // have not changed. Which is fine. - // TODO: Probably should refactor `beginWork` to split the bailout - // path from the normal path. I'm tempted to do a labeled break here - // but I won't :) - workInProgress.lanes = NoLanes; - return updateOffscreenComponent(current, workInProgress, renderLanes); - } + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } else { - if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } else { - // An update was scheduled on this fiber, but there are no new props - // nor legacy context. Set this to false. If an update queue or context - // consumer produces a changed value, it will set this to true. Otherwise, - // the component will assume the children have not changed and bail out. - didReceiveUpdate = false; + 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 (!fiberRoot.hydrate) { + // 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 the container would already be empty). + workInProgress.flags |= Snapshot; + } } + + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + return null; } - } else { - didReceiveUpdate = false; - } // Before entering the begin phase, clear pending update priority. - // TODO: This assumes that we're about to evaluate the component and process - // the update queue. However, there's an exception: SimpleMemoComponent - // sometimes bails out later in the begin phase. This indicates that we should - // move this assignment out of the common path and into each branch. - workInProgress.lanes = NoLanes; + 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 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; + } - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderLanes - ); - } + 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. - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateLanes, - renderLanes - ); - } + var _wasHydrated = popHydrationState(); - case FunctionComponent: { - var _Component = workInProgress.type; - var unresolvedProps = workInProgress.pendingProps; - var resolvedProps = - workInProgress.elementType === _Component - ? unresolvedProps - : resolveDefaultProps(_Component, unresolvedProps); - return updateFunctionComponent( - current, - workInProgress, - _Component, - resolvedProps, - renderLanes - ); - } + 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. - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + if (finalizeInitialChildren(instance)) { + markUpdate(workInProgress); + } + } - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderLanes - ); + bubbleProperties(workInProgress); + return null; } - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); + case HostText: { + var newText = newProps; - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); + 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. - case HostText: - return updateHostText(); + updateHostText$1(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (!(workInProgress.stateNode !== null)) { + throw 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. + } - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); + var _rootContainerInstance = getRootHostContainer(); - case HostPortal: - return updatePortalComponent(current, workInProgress, renderLanes); + var _currentHostContext = getHostContext(); - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + var _wasHydrated2 = popHydrationState(); - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } - return updateForwardRef( - current, - workInProgress, - type, - _resolvedProps2, - renderLanes - ); + bubbleProperties(workInProgress); + return null; } - case Fragment: - return updateFragment(current, workInProgress, renderLanes); + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - case Mode: - return updateMode(current, workInProgress, renderLanes); + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); + return workInProgress; + } - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; + } - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + if (nextDidTimeout && !prevDidTimeout) { + // If this subtree is running in blocking mode we can suspend, + // otherwise we won't suspend. + // 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 & BlockingMode) !== 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; + + 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(); + } + } + } { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + // TODO: Only schedule updates if these values are non equal, i.e. it changed. + if (nextDidTimeout || prevDidTimeout) { + // If this boundary just timed out, schedule an effect to attach a + // retry listener to the promise. This flag is also used to hide the + // primary children. In mutation mode, we also need the flag to + // *unhide* children that were previously hidden, so check if this + // is currently timed out, too. + workInProgress.flags |= Update; + } + } - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); + 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 doens't support type casting in combiation with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment2.treeBaseDuration; + } } } } - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateLanes, - renderLanes - ); + return null; } - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateLanes, - renderLanes - ); - } + 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: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + // 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; - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + if (isContextProvider(_Component)) { + popContext(workInProgress); + } - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderLanes - ); + bubbleProperties(workInProgress); + return null; } case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); - } + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - case FundamentalComponent: { - break; - } + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } - case ScopeComponent: { - break; - } + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); - } + 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); - case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); - } - } + if (!cannotBeSuspended) { + var row = workInProgress.child; - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + while (row !== null) { + var suspended = findFirstSuspended(row); -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; -} + 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 thennables. Instead, we'll transfer its thennables 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. -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; -} + var newThennables = suspended.updateQueue; -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + 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. -{ - // 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; + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - 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; - } + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. - if (node === workInProgress) { - return; - } + return workInProgress.child; + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + row = row.sibling; + } + } - node = node.return; - } + 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. - node.sibling.return = node.return; - node = node.sibling; - } - }; + workInProgress.lanes = SomeRetryLane; - updateHostContainer = function(workInProgress) { - // Noop - }; + { + markSpawnedWork(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); - 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 (_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. - 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 _newThennables = _suspended.updateQueue; - 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`. + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + 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; + + { + markSpawnedWork(SomeRetryLane); + } + } + } - var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + 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; - 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 (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - if (updatePayload) { - markUpdate(workInProgress); - } - }; + renderState.last = renderedTail; + } + } - 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); - } - }; -} + 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. -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; + var suspenseContext = suspenseStackCursor.current; - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. - 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; + return next; } - break; + bubbleProperties(workInProgress); + return null; } - 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; + case ScopeComponent: { + break; + } - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; - 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; + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" + ) { + workInProgress.flags |= Update; } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; + } // Don't bubble properties for hidden children. + + if ( + !nextIsHidden || + includesSomeLane(subtreeRenderLanes, OffscreenLane) || + (workInProgress.mode & ConcurrentMode) === NoMode + ) { + bubbleProperties(workInProgress); } - break; + return null; } } -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; + { + 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(workInProgress, renderLanes) { switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - return null; - case ClassComponent: { var Component = workInProgress.type; @@ -15293,6 +16284,18 @@ function completeWork(current, workInProgress, renderLanes) { popContext(workInProgress); } + var flags = workInProgress.flags; + + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + return null; } @@ -15300,2330 +16303,2393 @@ function completeWork(current, workInProgress, renderLanes) { popHostContainer(workInProgress); popTopLevelContextObject(workInProgress); resetWorkInProgressVersions(); - var fiberRoot = workInProgress.stateNode; + var _flags = workInProgress.flags; - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; + if (!((_flags & DidCapture) === NoFlags)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); } - 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(); + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; + } - 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 (!fiberRoot.hydrate) { - // 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 the container would already be empty). - workInProgress.flags |= Snapshot; + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + + case SuspenseComponent: { + popSuspenseContext(workInProgress); + + var _flags2 = workInProgress.flags; + + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); } + + return workInProgress; } - updateHostContainer(workInProgress); return null; } - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + return null; + } - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } - } else { - if (!newProps) { - if (!(workInProgress.stateNode !== null)) { - throw 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. + case HostPortal: + popHostContainer(workInProgress); + return null; - return null; - } + case ContextProvider: + var context = workInProgress.type._context; + popProvider(context, workInProgress); + return null; + + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); + + return null; + + case CacheComponent: + return null; + + default: + return null; + } +} + +function unwindInterruptedWork(interruptedWork, renderLanes) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; + + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } - 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. + break; + } - var _wasHydrated = popHydrationState(); + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + resetWorkInProgressVersions(); + break; + } - 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. + case HostComponent: { + popHostContext(interruptedWork); + break; + } - if (finalizeInitialChildren(instance)) { - markUpdate(workInProgress); - } - } + case HostPortal: + popHostContainer(interruptedWork); + break; - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - return null; - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - case HostText: { - var newText = newProps; + case ContextProvider: + var context = interruptedWork.type._context; + popProvider(context, interruptedWork); + break; - 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. + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(interruptedWork); - updateHostText$1(current, workInProgress, oldText, newText); - } else { - if (typeof newText !== "string") { - if (!(workInProgress.stateNode !== null)) { - throw 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. - } + break; + } +} - var _rootContainerInstance = getRootHostContainer(); +function createCapturedValue(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} - var _currentHostContext = getHostContext(); +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - var _wasHydrated2 = popHydrationState(); +function showErrorDialog(boundary, errorInfo) { + var capturedError = { + componentStack: errorInfo.stack !== null ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + boundary !== null && boundary.tag === ClassComponent + ? boundary.stateNode + : null + }; + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } +function logCapturedError(boundary, errorInfo) { + try { + var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - return null; + if (logError === false) { + return; } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + var error = errorInfo.value; - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + if (error != null && error._suppressLogging) { + if (boundary.tag === ClassComponent) { + // The error is recoverable and was silenced. + // Ignore it and don't print the stack addendum. + // This is handy for testing error boundaries without noise. + return; + } // The error is fatal. Since the silencing might have + // been accidental, we'll surface it anyway. + // However, the browser would have silenced the original error + // so we'll print it first, and then print the stack addendum. - return workInProgress; + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + var componentName = source ? getComponentName(source.type) : null; + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; + var errorBoundaryName = getComponentName(boundary.type); - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); + if (errorBoundaryName) { + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; } - if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in blocking mode we can suspend, - // otherwise we won't suspend. - // 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 & BlockingMode) !== 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; - - 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 combinedMessage = + componentNameMessage + + "\n" + + componentStack + + "\n\n" + + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. + // We don't include the original error message and JS stack because the browser + // has already printed it. Even if the application swallows the error, it is still + // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - { - // TODO: Only schedule updates if these values are non equal, i.e. it changed. - if (nextDidTimeout || prevDidTimeout) { - // If this boundary just timed out, schedule an effect to attach a - // retry listener to the promise. This flag is also used to hide the - // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if this - // is currently timed out, too. - workInProgress.flags |= Update; - } - } + console["error"](combinedMessage); // Don't transform to our wrapper + } else { + // In production, we print the error directly. + // This will include the message, the JS stack, and anything the browser wants to show. + // We pass the error object instead of custom message so that the browser displays the error natively. + console["error"](error); // Don't transform to our wrapper + } + } catch (e) { + // This method must not throw, or React internal state will get messed up. + // If console.error is overridden, or logCapturedError() shows a dialog that throws, + // we want to report this error outside of the normal stack as a last resort. + // https://github.com/facebook/react/issues/13188 + setTimeout(function() { + throw e; + }); + } +} - return null; - } +var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); +function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". - return null; + update.payload = { + element: null + }; + var error = errorInfo.value; - case ContextProvider: - // Pop provider fiber - popProvider(workInProgress); - return null; + update.callback = function() { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; - 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; + return update; +} - if (isContextProvider(_Component)) { - popContext(workInProgress); - } +function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - return null; - } + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + update.payload = function() { + logCapturedError(fiber, errorInfo); + return getDerivedStateFromError(error$1); + }; + } - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - return null; + var inst = fiber.stateNode; + + if (inst !== null && typeof inst.componentDidCatch === "function") { + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); } - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; + if (typeof getDerivedStateFromError !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromError is + // not defined. + markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined - 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); + logCapturedError(fiber, errorInfo); + } - if (!cannotBeSuspended) { - var row = workInProgress.child; + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); - while (row !== null) { - var suspended = findFirstSuspended(row); + { + if (typeof getDerivedStateFromError !== "function") { + // If componentDidCatch is the only error boundary method defined, + // then it needs to call setState to recover from errors. + // If no state update is scheduled then the boundary will swallow the error. + if (!includesSomeLane(fiber.lanes, SyncLane)) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" + ); + } + } + } + }; + } else { + update.callback = function() { + markFailedErrorBoundaryForHotReloading(fiber); + }; + } - 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 thennables. Instead, we'll transfer its thennables 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. + return update; +} - var newThennables = suspended.updateQueue; +function attachPingListener(root, wakeable, lanes) { + // Attach a listener to the promise to "ping" the root and retry. But only if + // one does not already exist for the lanes we're currently rendering (which + // acts like a "thread ID" here). + var pingCache = root.pingCache; + var threadIDs; - if (newThennables !== null) { - workInProgress.updateQueue = newThennables; - workInProgress.flags |= Update; - } // Rerender the whole list, but this time, we'll force fallbacks - // to stay in place. - // Reset the effect list before doing the second pass since that's now invalid. + if (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap$1(); + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } else { + threadIDs = pingCache.get(wakeable); - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + if (!threadIDs.has(lanes)) { + // Memoize using the thread ID to prevent redundant listeners. + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); + } +} - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. +function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes +) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } + if ( + value !== null && + typeof value === "object" && + typeof value.then === "function" + ) { + // This is a wakeable. + var wakeable = value; + // A legacy mode Suspense quirk, only relevant to hook components. - row = row.sibling; - } - } + var tag = sourceFiber.tag; - 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. + if ( + (sourceFiber.mode & BlockingMode) === NoMode && + (tag === FunctionComponent || + tag === ForwardRef || + tag === SimpleMemoComponent) + ) { + var currentSource = sourceFiber.alternate; - workInProgress.lanes = SomeRetryLane; + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; + } + } - { - markSpawnedWork(SomeRetryLane); - } - } + var hasInvisibleParentBoundary = hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ); // Schedule the nearest Suspense to re-render the timed out view. + + var _workInProgress = returnFiber; + + do { + if ( + _workInProgress.tag === SuspenseComponent && + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) + ) { + // Found the nearest boundary. + // Stash the promise on the boundary fiber. If the boundary times out, we'll + // attach another listener to flip the boundary back to its normal state. + var wakeables = _workInProgress.updateQueue; + + if (wakeables === null) { + var updateQueue = new Set(); + updateQueue.add(wakeable); + _workInProgress.updateQueue = updateQueue; } 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); + wakeables.add(wakeable); + } // If the boundary is outside of blocking mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. In the commit phase, we'll schedule a + // subsequent synchronous update to re-render the Suspense. + // + // Note: It doesn't matter whether the component that suspended was + // inside a blocking mode tree. If the Suspense is outside of it, we + // should *not* suspend the commit. + // + // If the suspense boundary suspended itself suspended, we don't have to + // do this trick because nothing was partially started. We can just + // directly do a second pass over the fallback in this render and + // pretend we meant to render that directly. - 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. + if ( + (_workInProgress.mode & BlockingMode) === NoMode && + _workInProgress !== returnFiber + ) { + _workInProgress.flags |= DidCapture; + sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. + // But we shouldn't call any lifecycle methods or callbacks. Remove + // all lifecycle effect tags. - var _newThennables = _suspended.updateQueue; + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; + if (sourceFiber.tag === ClassComponent) { + var currentSourceFiber = sourceFiber.alternate; + + if (currentSourceFiber === null) { + // This is a new mount. Change the tag so it's not mistaken for a + // completed class component. For example, we should not call + // componentWillUnmount if it is deleted. + sourceFiber.tag = IncompleteClassComponent; + } else { + // When we try rendering again, we should not reuse the current fiber, + // since it's known to be in an inconsistent state. Use a force update to + // prevent a bail out. + var update = createUpdate(NoTimestamp, SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update); } + } // The source fiber did not complete. Mark it with Sync priority to + // indicate that it still has pending work. - cutOffTailIfNeeded(renderState, true); // This might have been modified. + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We need to delete the row we just rendered. - // Reset the effect list to what it was before we rendered this - // child. The nested children have already appended themselves. - var lastEffect = (workInProgress.lastEffect = - renderState.lastEffect); // Remove any effects that were appended after this point. + return; + } // Confirmed that the boundary is in a concurrent mode tree. Continue + // with the normal suspend path. + // + // After this we'll use a set of heuristics to determine whether this + // render pass will run to completion or restart or "suspend" the commit. + // The actual logic for this is spread out in different places. + // + // This first principle is that if we're going to suspend when we complete + // a root, then we should also restart if we get an update or ping that + // might unsuspend it, and vice versa. The only reason to suspend is + // because you think you might want to restart before committing. However, + // it doesn't make sense to restart only while in the period we're suspended. + // + // Restarting too aggressively is also not good because it starves out any + // intermediate loading state. So we use heuristics to determine when. + // Suspense Heuristics + // + // If nothing threw a Promise or all the same fallbacks are already showing, + // then don't suspend/restart. + // + // If this is an initial render of a new tree of Suspense boundaries and + // those trigger a fallback, then don't suspend/restart. We want to ensure + // that we can show the initial loading state as quickly as possible. + // + // If we hit a "Delayed" case, such as when we'd switch from content back into + // a fallback, then we should always suspend/restart. Transitions apply + // to this case. If none is defined, JND is used instead. + // + // If we're already showing a fallback and it gets "retried", allowing us to show + // another level, but there's still an inner boundary that would show a fallback, + // then we suspend/restart for 500ms since the last time we showed a fallback + // anywhere in the tree. This effectively throttles progressive loading into a + // consistent train of commits. This also gives us an opportunity to restart to + // get to the completed state slightly earlier. + // + // If there's ambiguity due to batching it's resolved in preference of: + // 1) "delayed", 2) "initial render", 3) "retry". + // + // We want to ensure that a "busy" state doesn't get force committed. We want to + // ensure that new initial loading states can commit as soon as possible. - if (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + attachPingListener(root, wakeable, rootRenderLanes); + _workInProgress.flags |= ShouldCapture; + _workInProgress.lanes = rootRenderLanes; + return; + } // This boundary already captured during this render. Continue to the next + // boundary. - 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 = _workInProgress.return; + } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. + // TODO: Use invariant so the message is stripped in prod? - workInProgress.lanes = SomeRetryLane; + value = new Error( + (getComponentName(sourceFiber.type) || "A React component") + + " suspended while rendering, but no fallback UI was specified.\n" + + "\n" + + "Add a component higher in the tree to " + + "provide a loading indicator or placeholder to display." + ); + } // We didn't find a boundary that could handle this type of exception. Start + // over and traverse parent path again, this time treating the exception + // as an error. - { - markSpawnedWork(SomeRetryLane); - } - } - } + renderDidError(); + value = createCapturedValue(value, sourceFiber); + var workInProgress = returnFiber; - 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; + do { + switch (workInProgress.tag) { + case HostRoot: { + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); - renderState.last = renderedTail; - } + enqueueCapturedUpdate(workInProgress, _update); + return; } - 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.lastEffect = workInProgress.lastEffect; - 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. + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; - var suspenseContext = suspenseStackCursor.current; + if ( + (workInProgress.flags & DidCapture) === NoFlags && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + var _lane = pickArbitraryLane(rootRenderLanes); - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state - return next; - } + var _update2 = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); - return null; - } + enqueueCapturedUpdate(workInProgress, _update2); + return; + } - case FundamentalComponent: { - break; + break; } - case ScopeComponent: { - break; - } + workInProgress = workInProgress.return; + } while (workInProgress !== null); +} - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - if (current !== null) { - var _nextState = workInProgress.memoizedState; - var _prevState = current.memoizedState; - var prevIsHidden = _prevState !== null; - var nextIsHidden = _nextState !== null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - if ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" - ) { - workInProgress.flags |= Update; - } - } +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +var nextEffect = null; - return null; - } +var callComponentWillUnmountWithTimer = function(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + + { + instance.componentWillUnmount(); } +}; // Capture errors so they don't interrupt unmounting. +function safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance +) { { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, unmountError); + } } } -function unwindWork(workInProgress, renderLanes) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; - - if (isContextProvider(Component)) { - popContext(workInProgress); - } - - var flags = workInProgress.flags; - - if (flags & ShouldCapture) { - workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; +function safelyDetachRef(current, nearestMountedAncestor) { + var ref = current.ref; - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); + if (ref !== null) { + if (typeof ref === "function") { + { + { + invokeGuardedCallback(null, ref, null, null); } - return workInProgress; + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, refError); + } } - - return null; + } else { + ref.current = null; } + } +} - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - var _flags = workInProgress.flags; - - if (!((_flags & DidCapture) === NoFlags)) { - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - - workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; - return workInProgress; - } +function safelyCallDestroy(current, nearestMountedAncestor, destroy) { + { + invokeGuardedCallback(null, destroy, null); - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, error); } + } +} - case SuspenseComponent: { - popSuspenseContext(workInProgress); +var focusedInstanceHandle = null; +var shouldFireAfterActiveInstanceBlur = false; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = prepareForCommit(root.containerInfo); + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber - var _flags2 = workInProgress.flags; + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + focusedInstanceHandle = null; + return shouldFire; +} - if (_flags2 & ShouldCapture) { - workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. +function commitBeforeMutationEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + var deletions = fiber.deletions; - return workInProgress; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var deletion = deletions[i]; + commitBeforeMutationEffectsDeletion(deletion); } - - return null; } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been - // caught by a nested boundary. If not, it should bubble through. + var child = fiber.child; - return null; + if ( + (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && + child !== null + ) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitBeforeMutationEffects_complete(); } - - case HostPortal: - popHostContainer(workInProgress); - return null; - - case ContextProvider: - popProvider(workInProgress); - return null; - - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(workInProgress); - return null; - - default: - return null; } } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; +function commitBeforeMutationEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitBeforeMutationEffectsOnFiber, + null, + fiber + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - break; + resetCurrentFiber(); } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - resetWorkInProgressVersions(); - break; - } + var sibling = fiber.sibling; - case HostComponent: { - popHostContext(interruptedWork); - break; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - case HostPortal: - popHostContainer(interruptedWork); - break; - - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; - - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; + nextEffect = fiber.return; + } +} - case ContextProvider: - popProvider(interruptedWork); - break; +function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(interruptedWork); - break; + if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { + // Check to see if the focused element was inside of a hidden (Suspense) subtree. + // TODO: Move this out of the hot path using a dedicated effect tag. + if ( + finishedWork.tag === SuspenseComponent && + isSuspenseBoundaryBeingHidden(current, finishedWork) && + doesFiberContain(finishedWork, focusedInstanceHandle) + ) { + shouldFireAfterActiveInstanceBlur = true; + } } -} -function createCapturedValue(value, source) { - // If the value is an error, call this function immediately after it is thrown - // so the stack is accurate. - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(finishedWork); -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + break; + } -function showErrorDialog(boundary, errorInfo) { - var capturedError = { - componentStack: errorInfo.stack !== null ? errorInfo.stack : "", - error: errorInfo.value, - errorBoundary: - boundary !== null && boundary.tag === ClassComponent - ? boundary.stateNode - : null - }; - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + case ClassComponent: { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + var instance = finishedWork.stateNode; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. -function logCapturedError(boundary, errorInfo) { - try { - var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (logError === false) { - return; - } + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - var error = errorInfo.value; + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - if (true) { - var source = errorInfo.source; - var stack = errorInfo.stack; - var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - if (error != null && error._suppressLogging) { - if (boundary.tag === ClassComponent) { - // The error is recoverable and was silenced. - // Ignore it and don't print the stack addendum. - // This is handy for testing error boundaries without noise. - return; - } // The error is fatal. Since the silencing might have - // been accidental, we'll surface it anyway. - // However, the browser would have silenced the original error - // so we'll print it first, and then print the stack addendum. + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); + + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + + break; } - var componentName = source ? getComponentName(source.type) : null; - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; - var errorBoundaryName = getComponentName(boundary.type); + case HostRoot: { + { + var root = finishedWork.stateNode; + clearContainer(root.containerInfo); + } - if (errorBoundaryName) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); - } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + break; } - var combinedMessage = - componentNameMessage + - "\n" + - componentStack + - "\n\n" + - ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. - // We don't include the original error message and JS stack because the browser - // has already printed it. Even if the application swallows the error, it is still - // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + break; - console["error"](combinedMessage); // Don't transform to our wrapper - } else { - // In production, we print the error directly. - // This will include the message, the JS stack, and anything the browser wants to show. - // We pass the error object instead of custom message so that the browser displays the error natively. - console["error"](error); // Don't transform to our wrapper + default: { + { + 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." + ); + } + } } - } catch (e) { - // This method must not throw, or React internal state will get messed up. - // If console.error is overridden, or logCapturedError() shows a dialog that throws, - // we want to report this error outside of the normal stack as a last resort. - // https://github.com/facebook/react/issues/13188 - setTimeout(function() { - throw e; - }); + + resetCurrentFiber(); } } -var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; +function commitBeforeMutationEffectsDeletion(deletion) { + // TODO (effects) It would be nice to avoid calling doesFiberContain() + // Maybe we can repurpose one of the subtreeFlags positions for this instead? + // Use it to store which part of the tree the focused instance is in? + // This assumes we can safely determine that instance during the "render" phase. + if (doesFiberContain(deletion, focusedInstanceHandle)) { + shouldFireAfterActiveInstanceBlur = true; + } +} -function createRootErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor +) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property - // being called "element". + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - update.payload = { - element: null - }; - var error = errorInfo.value; + do { + if ((effect.tag & flags) === flags) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; - update.callback = function() { - onUncaughtError(error); - logCapturedError(fiber, errorInfo); - }; + if (destroy !== undefined) { + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + } + } - return update; + effect = effect.next; + } while (effect !== firstEffect); + } } -function createClassErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); - update.tag = CaptureUpdate; - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - - if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; - - update.payload = function() { - logCapturedError(fiber, errorInfo); - return getDerivedStateFromError(error$1); - }; - } +function commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - var inst = fiber.stateNode; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - { - markFailedErrorBoundaryForHotReloading(fiber); - } + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); - if (typeof getDerivedStateFromError !== "function") { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromError is - // not defined. - markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + { + var destroy = effect.destroy; - logCapturedError(fiber, errorInfo); - } + if (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; - var error$1 = errorInfo.value; - var stack = errorInfo.stack; - this.componentDidCatch(error$1, { - componentStack: stack !== null ? stack : "" - }); + if (destroy === null) { + addendum = + " You returned null. If your effect does not require clean " + + "up, return undefined (or nothing)."; + } else if (typeof destroy.then === "function") { + addendum = + "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + "useEffect(() => {\n" + + " async function fetchData() {\n" + + " // You can await here\n" + + " const response = await MyAPI.getData(someId);\n" + + " // ...\n" + + " }\n" + + " fetchData();\n" + + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } - { - if (typeof getDerivedStateFromError !== "function") { - // If componentDidCatch is the only error boundary method defined, - // then it needs to call setState to recover from errors. - // If no state update is scheduled then the boundary will swallow the error. - if (!includesSomeLane(fiber.lanes, SyncLane)) { error( - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s", + addendum ); } } } - }; - } else { - update.callback = function() { - markFailedErrorBoundaryForHotReloading(fiber); - }; - } - - return update; -} - -function attachPingListener(root, wakeable, lanes) { - // Attach a listener to the promise to "ping" the root and retry. But only if - // one does not already exist for the lanes we're currently rendering (which - // acts like a "thread ID" here). - var pingCache = root.pingCache; - var threadIDs; - - if (pingCache === null) { - pingCache = root.pingCache = new PossiblyWeakMap$1(); - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } else { - threadIDs = pingCache.get(wakeable); - - if (threadIDs === undefined) { - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } - } - if (!threadIDs.has(lanes)) { - // Memoize using the thread ID to prevent redundant listeners. - threadIDs.add(lanes); - var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); - wakeable.then(ping, ping); + effect = effect.next; + } while (effect !== firstEffect); } } -function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes +function commitLayoutEffectOnFiber( + finishedRoot, + current, + finishedWork, + committedLanes ) { - // The source fiber did not complete. - sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. - - sourceFiber.firstEffect = sourceFiber.lastEffect = null; - - if ( - value !== null && - typeof value === "object" && - typeof value.then === "function" - ) { - // This is a wakeable. - var wakeable = value; - - if ((sourceFiber.mode & BlockingMode) === NoMode) { - // Reset the memoizedState to what it was before we attempted - // to render it. - var currentSource = sourceFiber.alternate; + if ((finishedWork.flags & (Update | Callback)) !== NoFlags) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent 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. + { + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } - if (currentSource) { - sourceFiber.updateQueue = currentSource.updateQueue; - sourceFiber.memoizedState = currentSource.memoizedState; - sourceFiber.lanes = currentSource.lanes; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; + break; } - } - - var hasInvisibleParentBoundary = hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ); // Schedule the nearest Suspense to re-render the timed out view. - - var _workInProgress = returnFiber; - do { - if ( - _workInProgress.tag === SuspenseComponent && - shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) - ) { - // Found the nearest boundary. - // Stash the promise on the boundary fiber. If the boundary times out, we'll - // attach another listener to flip the boundary back to its normal state. - var wakeables = _workInProgress.updateQueue; + case ClassComponent: { + var instance = finishedWork.stateNode; - if (wakeables === null) { - var updateQueue = new Set(); - updateQueue.add(wakeable); - _workInProgress.updateQueue = updateQueue; - } else { - wakeables.add(wakeable); - } // If the boundary is outside of blocking mode, we should *not* - // suspend the commit. Pretend as if the suspended component rendered - // null and keep rendering. In the commit phase, we'll schedule a - // subsequent synchronous update to re-render the Suspense. - // - // Note: It doesn't matter whether the component that suspended was - // inside a blocking mode tree. If the Suspense is outside of it, we - // should *not* suspend the commit. + if (finishedWork.flags & Update) { + if (current === null) { + // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if ((_workInProgress.mode & BlockingMode) === NoMode) { - _workInProgress.flags |= DidCapture; - sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. - // But we shouldn't call any lifecycle methods or callbacks. Remove - // all lifecycle effect tags. + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + { + instance.componentDidMount(); + } + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - if (sourceFiber.tag === ClassComponent) { - var currentSourceFiber = sourceFiber.alternate; + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (currentSourceFiber === null) { - // This is a new mount. Change the tag so it's not mistaken for a - // completed class component. For example, we should not call - // componentWillUnmount if it is deleted. - sourceFiber.tag = IncompleteClassComponent; - } else { - // When we try rendering again, we should not reuse the current fiber, - // since it's known to be in an inconsistent state. Use a force update to - // prevent a bail out. - var update = createUpdate(NoTimestamp, SyncLane); - update.tag = ForceUpdate; - enqueueUpdate(sourceFiber, update); + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } } - } // The source fiber did not complete. Mark it with Sync priority to - // indicate that it still has pending work. - sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. - return; - } // Confirmed that the boundary is in a concurrent mode tree. Continue - // with the normal suspend path. - // - // After this we'll use a set of heuristics to determine whether this - // render pass will run to completion or restart or "suspend" the commit. - // The actual logic for this is spread out in different places. - // - // This first principle is that if we're going to suspend when we complete - // a root, then we should also restart if we get an update or ping that - // might unsuspend it, and vice versa. The only reason to suspend is - // because you think you might want to restart before committing. However, - // it doesn't make sense to restart only while in the period we're suspended. - // - // Restarting too aggressively is also not good because it starves out any - // intermediate loading state. So we use heuristics to determine when. - // Suspense Heuristics - // - // If nothing threw a Promise or all the same fallbacks are already showing, - // then don't suspend/restart. - // - // If this is an initial render of a new tree of Suspense boundaries and - // those trigger a fallback, then don't suspend/restart. We want to ensure - // that we can show the initial loading state as quickly as possible. - // - // If we hit a "Delayed" case, such as when we'd switch from content back into - // a fallback, then we should always suspend/restart. Transitions apply - // to this case. If none is defined, JND is used instead. - // - // If we're already showing a fallback and it gets "retried", allowing us to show - // another level, but there's still an inner boundary that would show a fallback, - // then we suspend/restart for 500ms since the last time we showed a fallback - // anywhere in the tree. This effectively throttles progressive loading into a - // consistent train of commits. This also gives us an opportunity to restart to - // get to the completed state slightly earlier. - // - // If there's ambiguity due to batching it's resolved in preference of: - // 1) "delayed", 2) "initial render", 3) "retry". - // - // We want to ensure that a "busy" state doesn't get force committed. We want to - // ensure that new initial loading states can commit as soon as possible. + var updateQueue = finishedWork.updateQueue; - attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; - _workInProgress.lanes = rootRenderLanes; - return; - } // This boundary already captured during this render. Continue to the next - // boundary. + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - _workInProgress = _workInProgress.return; - } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. - // TODO: Use invariant so the message is stripped in prod? + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - value = new Error( - (getComponentName(sourceFiber.type) || "A React component") + - " suspended while rendering, but no fallback UI was specified.\n" + - "\n" + - "Add a component higher in the tree to " + - "provide a loading indicator or placeholder to display." - ); - } // We didn't find a boundary that could handle this type of exception. Start - // over and traverse parent path again, this time treating the exception - // as an error. + commitUpdateQueue(finishedWork, updateQueue, instance); + } - renderDidError(); - value = createCapturedValue(value, sourceFiber); - var workInProgress = returnFiber; + break; + } - do { - switch (workInProgress.tag) { case HostRoot: { - var _errorInfo = value; - workInProgress.flags |= ShouldCapture; - var lane = pickArbitraryLane(rootRenderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; + + if (_updateQueue !== null) { + var _instance = null; + + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; + + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + } - var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } - enqueueCapturedUpdate(workInProgress, _update); - return; + break; } - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var instance = workInProgress.stateNode; + case HostComponent: { + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. - if ( - (workInProgress.flags & DidCapture) === NoFlags && - (typeof ctor.getDerivedStateFromError === "function" || - (instance !== null && - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance))) - ) { - workInProgress.flags |= ShouldCapture; + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + } - var _lane = pickArbitraryLane(rootRenderLanes); + break; + } - workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + case HostText: { + // We have no life-cycles associated with text. + break; + } - var _update2 = createClassErrorUpdate( - workInProgress, - errorInfo, - _lane - ); + case HostPortal: { + // We have no life-cycles associated with portals. + break; + } - enqueueCapturedUpdate(workInProgress, _update2); - return; + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); + var phase = current === null ? "mount" : "update"; + + if (typeof onRender === "function") { + { + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + } + } } break; + } + + case SuspenseComponent: { + break; + } + + case SuspenseListComponent: + case IncompleteClassComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + break; + + default: { + 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." + ); + } } + } - workInProgress = workInProgress.return; - } while (workInProgress !== null); + { + if (finishedWork.flags & Ref) { + commitAttachRef(finishedWork); + } + } } -var didWarnAboutUndefinedSnapshotBeforeUpdate = null; +function hideOrUnhideAllChildren(finishedWork, isHidden) { + { + // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. + var node = finishedWork; -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + while (true) { + if (node.tag === HostComponent) { + var instance = node.stateNode; -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } + } else if (node.tag === HostText) { + var _instance3 = node.stateNode; -var callComponentWillUnmountWithTimer = function(current, instance) { - instance.props = current.memoizedProps; - instance.state = current.memoizedState; + if (isHidden) { + hideTextInstance(); + } else { + unhideTextInstance(_instance3, node.memoizedProps); + } + } else if ( + (node.tag === OffscreenComponent || + node.tag === LegacyHiddenComponent) && + node.memoizedState !== null && + node !== finishedWork + ); + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - { - instance.componentWillUnmount(); - } -}; // Capture errors so they don't interrupt unmounting. + if (node === finishedWork) { + return; + } -function safelyCallComponentWillUnmount(current, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance - ); + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; + } - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; } } } -function safelyDetachRef(current) { - var ref = current.ref; +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; + + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; + + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag + if (typeof ref === "function") { { - { - invokeGuardedCallback(null, ref, null, null); - } - - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); - } + ref(instanceToUse); } } else { - ref.current = null; + { + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentName(finishedWork.type) + ); + } + } + + ref.current = instanceToUse; } } } -function safelyCallDestroy(current, destroy) { - { - invokeGuardedCallback(null, destroy, null); +function commitDetachRef(current) { + var currentRef = current.ref; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, error); + if (currentRef !== null) { + if (typeof currentRef === "function") { + { + 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 commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { +function commitUnmount( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + onCommitUnmount(current); + + switch (current.tag) { case FunctionComponent: case ForwardRef: + case MemoComponent: case SimpleMemoComponent: { - return; - } + var updateQueue = current.updateQueue; - case ClassComponent: { - if (finishedWork.flags & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - var instance = finishedWork.stateNode; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + + if (destroy !== undefined) { + if ((tag & Layout) !== NoFlags$1) { + { + safelyCallDestroy(current, nearestMountedAncestor, destroy); + } } } - } - - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + effect = effect.next; + } while (effect !== firstEffect); + } + } - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); + return; + } - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); - } - } + case ClassComponent: { + safelyDetachRef(current, nearestMountedAncestor); + var instance = current.stateNode; - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance + ); } return; } - case HostRoot: { + 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. { - if (finishedWork.flags & Snapshot) { - var root = finishedWork.stateNode; - clearContainer(root.containerInfo); - } + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } return; } - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types + case DehydratedFragment: { 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." - ); + case ScopeComponent: { + return; + } } } -function commitHookEffectListUnmount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function commitNestedUnmounts( + finishedRoot, + root, + nearestMountedAncestor, + renderPriorityLevel +) { + // 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; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + 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. - do { - if ((effect.tag & tag) === tag) { - // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + 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 (destroy !== undefined) { - destroy(); - } + if (node === root) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; } - effect = effect.next; - } while (effect !== firstEffect); + 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. + // It also prevents events from bubbling from within disconnected components. + // + // Ideally, we should also clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. + // This child itself will be GC:ed when the parent updates the next time. + // + // Note that we can't clear child or sibling pointers yet. + // They're needed for passive effects and for findDOMNode. + // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). + // + // Don't reset the alternate yet, either. We need that so we can detach the + // alternate's fields in the passive phase. Clearing the return pointer is + // sufficient for findDOMNode semantics. + fiber.return = null; +} + +function detachFiberAfterEffects(fiber) { + // Null out fields to improve GC for references that may be lingering (e.g. DevTools). + // Note that we already cleared the return pointer in detachFiberMutation(). + fiber.alternate = null; + fiber.child = null; + fiber.deletions = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.sibling = null; + fiber.stateNode = null; + fiber.updateQueue = null; + + { + fiber._debugOwner = null; } } -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function getHostParentFiber(fiber) { + var parent = fiber.return; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + while (parent !== null) { + if (isHostParent(parent)) { + return parent; + } - do { - if ((effect.tag & tag) === tag) { - // Mount - var create = effect.create; - effect.destroy = create(); + parent = parent.return; + } - { - var destroy = effect.destroy; + { + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + } +} - if (destroy !== undefined && typeof destroy !== "function") { - var addendum = void 0; +function isHostParent(fiber) { + return ( + fiber.tag === HostComponent || + fiber.tag === HostRoot || + fiber.tag === HostPortal + ); +} - if (destroy === null) { - addendum = - " You returned null. If your effect does not require clean " + - "up, return undefined (or nothing)."; - } else if (typeof destroy.then === "function") { - addendum = - "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + - "Instead, write the async function inside your effect " + - "and call it immediately:\n\n" + - "useEffect(() => {\n" + - " async function fetchData() {\n" + - " // You can await here\n" + - " const response = await MyAPI.getData(someId);\n" + - " // ...\n" + - " }\n" + - " fetchData();\n" + - "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + - "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; - } else { - addendum = " You returned: " + destroy; - } +function getHostSibling(fiber) { + // We're going to search forward into the tree until we find a sibling host + // node. Unfortunately, if multiple insertions are done in a row we have to + // search past them. This leads to exponential search for the next sibling. + // TODO: Find a more efficient way to do this. + var node = fiber; - error( - "An effect function must not return anything besides a function, " + - "which is used for clean-up.%s", - addendum - ); - } - } + siblings: while (true) { + // If we didn't find anything, let's try the next sibling. + while (node.sibling === null) { + if (node.return === null || isHostParent(node.return)) { + // If we pop out of the root or hit the parent the fiber we are the + // last sibling. + return null; } - effect = effect.next; - } while (effect !== firstEffect); - } -} - -function schedulePassiveEffects(finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + node = node.return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + node.sibling.return = node.return; + node = node.sibling; - do { - var _effect = effect, - next = _effect.next, - tag = _effect.tag; + while ( + node.tag !== HostComponent && + node.tag !== HostText && + node.tag !== DehydratedFragment + ) { + // If it is not host node and, we might have a host node inside it. + // Try to search down until we find one. + if (node.flags & Placement) { + // If we don't have a child, try the siblings instead. + continue siblings; + } // If we don't have a child, try the siblings instead. + // We also skip portals because they are not part of this host tree. - if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); - enqueuePendingPassiveHookEffectMount(finishedWork, effect); + if (node.child === null || node.tag === HostPortal) { + continue siblings; + } else { + node.child.return = node; + node = node.child; } + } // Check if this host node is stable or about to be placed. - effect = next; - } while (effect !== firstEffect); + if (!(node.flags & Placement)) { + // Found it! + return node.stateNode; + } } } -function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - // At this point layout effects have already been destroyed (during mutation phase). - // This is done to prevent 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. - { - commitHookEffectListMount(Layout | HasEffect, finishedWork); - } +function commitPlacement(finishedWork) { + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. - schedulePassiveEffects(finishedWork); - return; - } + var parent; + var isContainer; + var parentStateNode = parentFiber.stateNode; - case ClassComponent: { - var instance = finishedWork.stateNode; + switch (parentFiber.tag) { + case HostComponent: + parent = parentStateNode; + isContainer = false; + break; - if (finishedWork.flags & Update) { - if (current === null) { - // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + case HostRoot: + parent = parentStateNode.containerInfo; + isContainer = true; + break; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + case HostPortal: + parent = parentStateNode.containerInfo; + isContainer = true; + break; + // eslint-disable-next-line-no-fallthrough - { - instance.componentDidMount(); - } - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + default: { + throw Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); + } + } - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (parentFiber.flags & ContentReset) { + parentFiber.flags &= ~ContentReset; + } - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - } - } // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. + if (isContainer) { + insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); + } else { + insertOrAppendPlacementNode(finishedWork, before, parent); + } +} - var updateQueue = finishedWork.updateQueue; +function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - if (updateQueue !== null) { - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (isHost) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + if (before) { + insertInContainerBefore(parent); + } else { + appendChildToContainer(parent, stateNode); + } + } else if (tag === HostPortal); + else { + var child = node.child; + + if (child !== null) { + insertOrAppendPlacementNodeIntoContainer(child, before, parent); + var sibling = child.sibling; - commitUpdateQueue(finishedWork, updateQueue, instance); + while (sibling !== null) { + insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); + sibling = sibling.sibling; } - - return; } + } +} - case HostRoot: { - // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. - var _updateQueue = finishedWork.updateQueue; +function insertOrAppendPlacementNode(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - if (_updateQueue !== null) { - var _instance = null; + if (isHost) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; + if (before) { + insertBefore(parent, stateNode, before); + } else { + appendChild(parent, stateNode); + } + } else if (tag === HostPortal); + else { + var child = node.child; - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } + if (child !== null) { + insertOrAppendPlacementNode(child, before, parent); + var sibling = child.sibling; - commitUpdateQueue(finishedWork, _updateQueue, _instance); + while (sibling !== null) { + insertOrAppendPlacementNode(sibling, before, parent); + sibling = sibling.sibling; } - - return; } + } +} - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. +function unmountHostComponents( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + // 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. - if (current === null && finishedWork.flags & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - } + var currentParentIsValid = false; // Note: these two variables *must* always be updated together. - return; - } + var currentParent; + var currentParentIsContainer; - case HostText: { - // We have no life-cycles associated with text. - return; - } + while (true) { + if (!currentParentIsValid) { + var parent = node.return; - case HostPortal: { - // We have no life-cycles associated with portals. - return; - } + findParent: while (true) { + if (!(parent !== null)) { + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + } - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + var parentStateNode = parent.stateNode; - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - current === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } - } - } + switch (parent.tag) { + case HostComponent: + currentParent = parentStateNode; + currentParentIsContainer = false; + break findParent; - return; - } + case HostRoot: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; - case SuspenseComponent: { - return; - } + case HostPortal: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; + } - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - case OffscreenComponent: - case LegacyHiddenComponent: - return; - } + parent = parent.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." - ); - } -} + currentParentIsValid = true; + } -function hideOrUnhideAllChildren(finishedWork, isHidden) { - { - // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. - var node = finishedWork; + 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. - while (true) { - if (node.tag === HostComponent) { - var instance = node.stateNode; + 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. - if (isHidden) { - hideInstance(instance); - } else { - unhideInstance(node.stateNode, node.memoizedProps); - } - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + node.child.return = node; + node = node.child; + continue; + } + } else { + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below. - if (isHidden) { - hideTextInstance(); - } else { - unhideTextInstance(_instance3, node.memoizedProps); - } - } else if ( - (node.tag === OffscreenComponent || - node.tag === LegacyHiddenComponent) && - node.memoizedState !== null && - node !== finishedWork - ); - else if (node.child !== null) { + if (node.child !== null) { node.child.return = node; node = node.child; continue; } + } - if (node === finishedWork) { + if (node === current) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === current) { return; } - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - return; - } + node = node.return; - 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; } - - node.sibling.return = node.return; - node = node.sibling; } + + node.sibling.return = node.return; + node = node.sibling; } } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; - - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; - - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; - - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag - - if (typeof ref === "function") { - { - ref(instanceToUse); - } - } else { - { - if (!ref.hasOwnProperty("current")) { - error( - "Unexpected ref object provided for %s. " + - "Use either a ref-setter function or React.createRef().", - getComponentName(finishedWork.type) - ); - } - } - - ref.current = instanceToUse; - } +function commitDeletion( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + { + // Recursively delete all host nodes from the parent. + // Detach refs and call componentWillUnmount() on the whole subtree. + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } -} -function commitDetachRef(current) { - var currentRef = current.ref; + var alternate = current.alternate; + detachFiberMutation(current); - if (currentRef !== null) { - if (typeof currentRef === "function") { - { - currentRef(null); - } - } else { - currentRef.current = null; - } + if (alternate !== null) { + detachFiberMutation(alternate); } -} // 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, renderPriorityLevel) { - onCommitUnmount(current); +} - switch (current.tag) { +function commitWork(current, finishedWork) { + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: case SimpleMemoComponent: { - var updateQueue = current.updateQueue; + // 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. + { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + case ClassComponent: { + return; + } + + 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. - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; + var oldProps = current !== null ? current.memoizedProps : newProps; + var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. - if (destroy !== undefined) { - if ((tag & Passive$1) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(current, effect); - } else { - { - safelyCallDestroy(current, destroy); - } - } - } + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; - effect = effect.next; - } while (effect !== firstEffect); + if (updatePayload !== null) { + commitUpdate(instance, updatePayload, type, oldProps, newProps); } } return; } - case ClassComponent: { - safelyDetachRef(current); - var instance = current.stateNode; - - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, instance); + case HostText: { + if (!(finishedWork.stateNode !== null)) { + throw 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; + commitTextUpdate(textInstance, oldText, newText); return; } - case HostComponent: { - safelyDetachRef(current); + case HostRoot: { return; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - unmountHostComponents(finishedRoot, current); - } + case Profiler: { + return; + } + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); return; } - case FundamentalComponent: { + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } - case DehydratedFragment: { + case IncompleteClassComponent: { return; } case ScopeComponent: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + var newState = finishedWork.memoizedState; + var isHidden = newState !== null; + hideOrUnhideAllChildren(finishedWork, isHidden); 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 commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { - // 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; +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; - while (true) { - commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. + if (newState !== null) { + markCommitTimeOfFallback(); - 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; + { + // Hide the Offscreen component that contains the primary children. TODO: + // Ideally, this effect would have been scheduled on the Offscreen fiber + // itself. That's how unhiding works: the Offscreen component schedules an + // effect on itself. However, in this case, the component didn't complete, + // so the fiber was never added to the effect list in the normal path. We + // could have appended it to the effect list in the Suspense component's + // second pass, but doing it this way is less complicated. This would be + // simpler if we got rid of the effect list and traversed the tree, like + // we're planning to do. + var primaryChildParent = finishedWork.child; + hideOrUnhideAllChildren(primaryChildParent, true); } + } +} - if (node === root) { - return; - } +function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; - node = node.return; + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); } - node.sibling.return = node.return; - node = node.sibling; - } -} + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); -function detachFiberMutation(fiber) { - // Cut off the return pointers to disconnect it from the tree. Ideally, we - // should clear the child pointer of the parent alternate to let this - // get GC:ed but we don't know which for sure which parent is the current - // one so we'll settle for GC:ing the subtree of this child. This child - // itself will be GC:ed when the parent updates the next time. - // Note: we cannot null out sibling here, otherwise it can cause issues - // with findDOMNode and how it requires the sibling field to carry out - // traversal in a later effect. See PR #16820. We now clear the sibling - // field after effects, see: detachFiberAfterEffects. - // - // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. - // It may be required if the current component is an error boundary, - // and one of its descendants throws while unmounting a passive effect. - fiber.alternate = null; - fiber.child = null; - fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.return = null; - fiber.updateQueue = null; + if (!retryCache.has(wakeable)) { + { + if (wakeable.__reactDoNotTraceInteractions !== true) { + retry = tracing.unstable_wrap(retry); + } + } - { - fiber._debugOwner = null; + retryCache.add(wakeable); + wakeable.then(retry, retry); + } + }); } -} +} // This function detects when a Suspense boundary goes from visible to hidden. +// It returns false if the boundary is already hidden. +// TODO: Use an effect tag. -function getHostParentFiber(fiber) { - var parent = fiber.return; +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + if (current !== null) { + var oldState = current.memoizedState; - while (parent !== null) { - if (isHostParent(parent)) { - return parent; + if (oldState === null || oldState.dehydrated !== null) { + var newState = finishedWork.memoizedState; + return newState !== null && newState.dehydrated === null; } - - 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." - ); - } + return false; } -function isHostParent(fiber) { - return ( - fiber.tag === HostComponent || - fiber.tag === HostRoot || - fiber.tag === HostPortal - ); +function commitResetTextContent(current) { + resetTextContent(current.stateNode); } -function getHostSibling(fiber) { - // We're going to search forward into the tree until we find a sibling host - // node. Unfortunately, if multiple insertions are done in a row we have to - // search past them. This leads to exponential search for the next sibling. - // TODO: Find a more efficient way to do this. - var node = fiber; +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + nextEffect = firstChild; + commitMutationEffects_begin(root, renderPriorityLevel); +} - siblings: while (true) { - // If we didn't find anything, let's try the next sibling. - while (node.sibling === null) { - if (node.return === null || isHostParent(node.return)) { - // If we pop out of the root or hit the parent the fiber we are the - // last sibling. - return null; - } +function commitMutationEffects_begin(root, renderPriorityLevel) { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - node = node.return; - } + var deletions = fiber.deletions; - node.sibling.return = node.return; - node = node.sibling; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; - while ( - node.tag !== HostComponent && - node.tag !== HostText && - node.tag !== DehydratedFragment - ) { - // If it is not host node and, we might have a host node inside it. - // Try to search down until we find one. - if (node.flags & Placement) { - // If we don't have a child, try the siblings instead. - continue siblings; - } // If we don't have a child, try the siblings instead. - // We also skip portals because they are not part of this host tree. + { + invokeGuardedCallback( + null, + commitDeletion, + null, + root, + childToDelete, + fiber, + renderPriorityLevel + ); - if (node.child === null || node.tag === HostPortal) { - continue siblings; - } else { - node.child.return = node; - node = node.child; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(childToDelete, fiber, error); + } + } } - } // Check if this host node is stable or about to be placed. + } - if (!(node.flags & Placement)) { - // Found it! - return node.stateNode; + var child = fiber.child; + + if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitMutationEffects_complete(root, renderPriorityLevel); } } } -function commitPlacement(finishedWork) { - var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. - - var parent; - var isContainer; - var parentStateNode = parentFiber.stateNode; - - switch (parentFiber.tag) { - case HostComponent: - parent = parentStateNode; - isContainer = false; - break; - - case HostRoot: - parent = parentStateNode.containerInfo; - isContainer = true; - break; - - case HostPortal: - parent = parentStateNode.containerInfo; - isContainer = true; - break; - - case FundamentalComponent: - - // eslint-disable-next-line-no-fallthrough +function commitMutationEffects_complete(root, renderPriorityLevel) { + while (nextEffect !== null) { + var fiber = nextEffect; - default: { - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitMutationEffectsOnFiber, + null, + fiber, + root, + renderPriorityLevel ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); } - } - if (parentFiber.flags & ContentReset) { - parentFiber.flags &= ~ContentReset; - } + var sibling = fiber.sibling; - var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - if (isContainer) { - insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); - } else { - insertOrAppendPlacementNode(finishedWork, before, parent); + nextEffect = fiber.return; } } -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; +function commitMutationEffectsOnFiber(finishedWork, root, renderPriorityLevel) { + var flags = finishedWork.flags; - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (flags & ContentReset) { + commitResetTextContent(finishedWork); + } - if (before) { - insertInContainerBefore(parent); - } else { - appendChildToContainer(parent, stateNode); + if (flags & Ref) { + var current = finishedWork.alternate; + + if (current !== null) { + commitDetachRef(current); } - } else if (tag === HostPortal); - else { - var child = node.child; + } // 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. - if (child !== null) { - insertOrAppendPlacementNodeIntoContainer(child, before, parent); - var sibling = child.sibling; + var primaryFlags = flags & (Placement | Update | Hydrating); - while (sibling !== null) { - insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); - sibling = sibling.sibling; - } + 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; } - } -} -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; + 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. - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + finishedWork.flags &= ~Placement; // Update - if (before) { - insertBefore(parent, stateNode, before); - } else { - appendChild(parent, stateNode); + var _current = finishedWork.alternate; + commitWork(_current, finishedWork); + break; } - } else if (tag === HostPortal); - else { - var child = node.child; - if (child !== null) { - insertOrAppendPlacementNode(child, before, parent); - var sibling = child.sibling; + case Hydrating: { + finishedWork.flags &= ~Hydrating; + break; + } - while (sibling !== null) { - insertOrAppendPlacementNode(sibling, before, parent); - sibling = sibling.sibling; - } + case HydratingAndUpdate: { + finishedWork.flags &= ~Hydrating; // Update + + var _current2 = finishedWork.alternate; + commitWork(_current2, finishedWork); + break; + } + + case Update: { + var _current3 = finishedWork.alternate; + commitWork(_current3, finishedWork); + break; } } } -function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { - // 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. - - var currentParentIsValid = false; // Note: these two variables *must* always be updated together. - - var currentParent; - var currentParentIsContainer; +function commitLayoutEffects(finishedWork, root, committedLanes) { + nextEffect = finishedWork; + commitLayoutEffects_begin(finishedWork, root, committedLanes); +} - while (true) { - if (!currentParentIsValid) { - var parent = node.return; +function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; - findParent: while (true) { - if (!(parent !== null)) { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + } + } +} - var parentStateNode = parent.stateNode; +function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + while (nextEffect !== null) { + var fiber = nextEffect; - switch (parent.tag) { - case HostComponent: - currentParent = parentStateNode; - currentParentIsContainer = false; - break findParent; + if ((fiber.flags & LayoutMask) !== NoFlags) { + var current = fiber.alternate; - case HostRoot: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitLayoutEffectOnFiber, + null, + root, + current, + fiber, + committedLanes + ); - case HostPortal: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - parent = parent.return; + resetCurrentFiber(); } + } - currentParentIsValid = true; + if (fiber === subtreeRoot) { + nextEffect = null; + return; } - if (node.tag === HostComponent || node.tag === HostText) { - commitNestedUnmounts(finishedRoot, node); // After all the children have unmounted, it is now safe to remove the - // node from the tree. + var sibling = fiber.sibling; - 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. + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - node.child.return = node; - node = node.child; - continue; - } - } else { - commitUnmount(finishedRoot, node); // Visit children because we may find more host components below. + nextEffect = fiber.return; + } +} - if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - } +function commitPassiveMountEffects(root, finishedWork) { + nextEffect = finishedWork; + commitPassiveMountEffects_begin(finishedWork, root); +} - if (node === current) { - return; +function commitPassiveMountEffects_begin(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; + + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitPassiveMountEffects_complete(subtreeRoot, root); } + } +} - while (node.sibling === null) { - if (node.return === null || node.return === current) { - return; - } +function commitPassiveMountEffects_complete(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; - node = node.return; + if ((fiber.flags & Passive) !== NoFlags) { + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitPassiveMountOnFiber, + null, + root, + fiber + ); - 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; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); } } - node.sibling.return = node.return; - node = node.sibling; - } -} + if (fiber === subtreeRoot) { + nextEffect = null; + return; + } -function commitDeletion(finishedRoot, current, renderPriorityLevel) { - { - // Recursively delete all host nodes from the parent. - // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current); - } + var sibling = fiber.sibling; - var alternate = current.alternate; - detachFiberMutation(current); + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - if (alternate !== null) { - detachFiberMutation(alternate); + nextEffect = fiber.return; } } -function commitWork(current, finishedWork) { +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case MemoComponent: case SimpleMemoComponent: { - // 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. { - commitHookEffectListUnmount(Layout | HasEffect, finishedWork); + commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); } - return; + break; } + } +} - case ClassComponent: { - return; - } +function commitPassiveUnmountEffects(firstChild) { + nextEffect = firstChild; + commitPassiveUnmountEffects_begin(); +} - case HostComponent: { - var instance = finishedWork.stateNode; +function commitPassiveUnmountEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; + var child = fiber.child; - 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. + if ((nextEffect.flags & ChildDeletion) !== NoFlags) { + var deletions = fiber.deletions; - var oldProps = current !== null ? current.memoizedProps : newProps; - var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + nextEffect = fiberToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + fiberToDelete, + fiber + ); // Now that passive effects have been processed, it's safe to detach lingering pointers. - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; + var alternate = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); - if (updatePayload !== null) { - commitUpdate(instance, updatePayload, type, oldProps, newProps); + if (alternate !== null) { + detachFiberAfterEffects(alternate); + } } - } - - return; - } - - case HostText: { - if (!(finishedWork.stateNode !== null)) { - throw 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; - commitTextUpdate(textInstance, oldText, newText); - return; + nextEffect = fiber; + } } - case HostRoot: { - return; + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffects_complete(); } + } +} - case Profiler: { - return; - } +function commitPassiveUnmountEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; + if ((fiber.flags & Passive) !== NoFlags) { + setCurrentFiber(fiber); + commitPassiveUnmountOnFiber(fiber); + resetCurrentFiber(); } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } + var sibling = fiber.sibling; - case IncompleteClassComponent: { + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; return; } - case FundamentalComponent: { - break; - } + nextEffect = fiber.return; + } +} - case ScopeComponent: { - break; - } +function commitPassiveUnmountOnFiber(finishedWork) { + { + finishedWork.flags &= ~PassiveUnmountPendingDev; + var alternate = finishedWork.alternate; - case OffscreenComponent: - case LegacyHiddenComponent: { - var newState = finishedWork.memoizedState; - var isHidden = newState !== null; - hideOrUnhideAllChildren(finishedWork, isHidden); - return; + if (alternate !== null) { + alternate.flags &= ~PassiveUnmountPendingDev; } } - { - 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." - ); + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount( + Passive$1 | HasEffect, + finishedWork, + finishedWork.return + ); + } + + break; + } } } -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; +function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + deletedSubtreeRoot, + nearestMountedAncestor +) { + while (nextEffect !== null) { + var fiber = nextEffect; // Deletion effects fire in parent -> child order + // TODO: Check if fiber has a PassiveStatic flag - if (newState !== null) { - markCommitTimeOfFallback(); + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag - { - // Hide the Offscreen component that contains the primary children. TODO: - // Ideally, this effect would have been scheduled on the Offscreen fiber - // itself. That's how unhiding works: the Offscreen component schedules an - // effect on itself. However, in this case, the component didn't complete, - // so the fiber was never added to the effect list in the normal path. We - // could have appended it to the effect list in the Suspense component's - // second pass, but doing it this way is less complicated. This would be - // simpler if we got rid of the effect list and traversed the tree, like - // we're planning to do. - var primaryChildParent = finishedWork.child; - hideOrUnhideAllChildren(primaryChildParent, true); + if (child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ); } } } -function attachSuspenseRetryListeners(finishedWork) { - // If this boundary just timed out, then it will have a set of wakeables. - // For each wakeable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. - var wakeables = finishedWork.updateQueue; - - if (wakeables !== null) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; +function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot +) { + while (nextEffect !== null) { + var fiber = nextEffect; - if (retryCache === null) { - retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + if (fiber === deletedSubtreeRoot) { + nextEffect = null; + return; } - wakeables.forEach(function(wakeable) { - // Memoize using the boundary fiber to prevent redundant listeners. - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + var sibling = fiber.sibling; - if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - retryCache.add(wakeable); - wakeable.then(retry, retry); - } - }); + nextEffect = fiber.return; } -} // This function detects when a Suspense boundary goes from visible to hidden. -// It returns false if the boundary is already hidden. -// TODO: Use an effect tag. +} -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - if (current !== null) { - var oldState = current.memoizedState; +function commitPassiveUnmountInsideDeletedTreeOnFiber( + current, + nearestMountedAncestor +) { + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); + } - if (oldState === null || oldState.dehydrated !== null) { - var newState = finishedWork.memoizedState; - return newState !== null && newState.dehydrated === null; + break; } } - - return false; } -function commitResetTextContent(current) { - resetTextContent(current.stateNode); +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; } var COMPONENT_TYPE = 0; @@ -17705,8 +18771,7 @@ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. -var workInProgressRootPingedLanes = NoLanes; -var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train +var workInProgressRootPingedLanes = NoLanes; // The most recent time we committed a fallback. This lets us ensure a train // model where we don't commit new loading states in too quick succession. var globalMostRecentFallbackTime = 0; @@ -17725,16 +18790,13 @@ function resetRenderTimer() { function getRenderTargetTime() { return workInProgressRootRenderTargetTime; } -var nextEffect = null; var hasUncaughtError = false; var firstUncaughtError = null; -var legacyErrorBoundariesThatAlreadyFailed = null; +var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; -var pendingPassiveEffectsRenderPriority = NoPriority$1; +var pendingPassiveEffectsRenderPriority = NoPriority; var pendingPassiveEffectsLanes = NoLanes; -var pendingPassiveHookEffectsMount = []; -var pendingPassiveHookEffectsUnmount = []; var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; @@ -17752,13 +18814,10 @@ var spawnedWorkDuringRender = null; // If two updates are scheduled within the s // between the first and second call. var currentEventTime = NoTimestamp; -var currentEventWipLanes = NoLanes; -var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. +var currentEventTransitionLane = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. // We warn about state updates for unmounted components differently in this case. var isFlushingPassiveEffects = false; -var focusedInstanceHandle = null; -var shouldFireAfterActiveInstanceBlur = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -17783,63 +18842,41 @@ function requestUpdateLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 + return getCurrentPriorityLevel() === ImmediatePriority ? SyncLane : SyncBatchedLane; } // The algorithm for assigning an update to a lane should be stable for all - // updates at the same priority within the same event. To do this, the inputs - // to the algorithm must be the same. For example, we use the `renderLanes` - // to avoid choosing a lane that is already in the middle of rendering. - // - // However, the "included" lanes could be mutated in between updates in the - // same event, like if you perform an update inside `flushSync`. Or any other - // code path that might call `prepareFreshStack`. - // - // The trick we use is to cache the first of each of these inputs within an - // event. Then reset the cached values once we can be sure the event is over. - // Our heuristic for that is whenever we enter a concurrent work loop. - // - // We'll do the same for `currentEventPendingLanes` below. - - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; - } var isTransition = requestCurrentTransition() !== NoTransition; if (isTransition) { - if (currentEventPendingLanes !== NoLanes) { - currentEventPendingLanes = - mostRecentlyUpdatedRoot !== null - ? mostRecentlyUpdatedRoot.pendingLanes - : NoLanes; + if (currentEventTransitionLane === NoLane) { + currentEventTransitionLane = claimNextTransitionLane(); } - return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); + return currentEventTransitionLane; } // TODO: Remove this dependency on the Scheduler priority. // To do that, we're replacing it with an update lane priority. - var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. - // This couples React to the Scheduler internals, so we're replacing it - // with the currentUpdateLanePriority above. As an example of how this - // could be problematic, if we're not inside `Scheduler.runWithPriority`, - // then we'll get the priority of the current running Scheduler task, - // which is probably not what we want. + var schedulerPriority = getCurrentPriorityLevel(); // Find the correct lane based on priorities. Ideally, this would just be + // the update lane priority, but for now we're also checking for discrete + // updates and falling back to the scheduler priority. var lane; if ( // TODO: Temporary. We're removing the concept of discrete updates. (executionContext & DiscreteEventContext) !== NoContext && - schedulerPriority === UserBlockingPriority$1 + schedulerPriority === UserBlockingPriority ) { - lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); + lane = findUpdateLane(InputDiscreteLanePriority); } else { - var schedulerLanePriority = schedulerPriorityToLanePriority( - schedulerPriority - ); - - lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); + { + var schedulerLanePriority = schedulerPriorityToLanePriority( + schedulerPriority + ); + lane = findUpdateLane(schedulerLanePriority); + } } return lane; @@ -17855,16 +18892,12 @@ function requestRetryLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 + return getCurrentPriorityLevel() === ImmediatePriority ? SyncLane : SyncBatchedLane; } // See `requestUpdateLane` for explanation of `currentEventWipLanes` - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; - } - - return findRetryLane(currentEventWipLanes); + return claimNextRetryLane(); } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -17937,8 +18970,8 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority$1 || - priorityLevel === ImmediatePriority$1) + (priorityLevel === UserBlockingPriority || + priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority // discrete update per root so we can flush them early, if needed. @@ -17951,13 +18984,9 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, lane); - } // We use this when assigning a lane for a transition inside - // `requestUpdateLane`. We assume it's the same as the root being updated, - // since in the common case of a single root app it probably is. If it's not - // the same root, then it's not a huge deal, we just might batch more stuff - // together more than necessary. + } - mostRecentlyUpdatedRoot = root; + return root; } // This is split into a separate function so we can mark a fiber with pending // work without treating it as a typical update that originates from an event; // e.g. retrying a Suspense boundary isn't an update, but it does schedule work @@ -17979,7 +19008,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { ) { warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - } // Walk the parent path to the root and update the child expiration time. + } // Walk the parent path to the root and update the child lanes. var node = sourceFiber; var parent = sourceFiber.return; @@ -18008,6 +19037,20 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { } else { return null; } +} + +function isInterleavedUpdate(fiber, lane) { + return ( + // 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 && + (fiber.mode & BlockingMode) !== 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 + // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled. + deferRenderPhaseUpdateToNextBatch + ); } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the priority // of the existing task is the same as the priority of the next level that the @@ -18031,22 +19074,36 @@ function ensureRootIsScheduled(root, currentTime) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); - root.callbackNode = null; - root.callbackPriority = NoLanePriority; } + root.callbackNode = null; + root.callbackPriority = NoLanePriority; return; } // Check if there's an existing task. We may be able to reuse it. - if (existingCallbackNode !== null) { - var existingCallbackPriority = root.callbackPriority; + var existingCallbackPriority = root.callbackPriority; - if (existingCallbackPriority === newCallbackPriority) { - // The priority hasn't changed. We can reuse the existing task. Exit. - return; - } // The priority changed. Cancel the existing callback. We'll schedule a new - // one below. + if (existingCallbackPriority === newCallbackPriority) { + { + // If we're going to re-use an existing task, it needs to exist. + // Assume that discrete update microtasks are non-cancellable and null. + // TODO: Temporary until we confirm this warning is not fired. + if ( + existingCallbackNode == null && + existingCallbackPriority !== InputDiscreteLanePriority && + existingCallbackPriority !== SyncLanePriority + ) { + error( + "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue." + ); + } + } // The priority hasn't changed. We can reuse the existing task. Exit. + + return; + } + if (existingCallbackNode != null) { + // Cancel the existing callback. We'll schedule a new one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. @@ -18055,12 +19112,11 @@ function ensureRootIsScheduled(root, currentTime) { if (newCallbackPriority === SyncLanePriority) { // Special case: Sync React callbacks are scheduled on a special // internal queue - newCallbackNode = scheduleSyncCallback( - performSyncWorkOnRoot.bind(null, root) - ); + scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + newCallbackNode = null; } else if (newCallbackPriority === SyncBatchedLanePriority) { newCallbackNode = scheduleCallback( - ImmediatePriority$1, + ImmediatePriority, performSyncWorkOnRoot.bind(null, root) ); } else { @@ -18078,12 +19134,11 @@ function ensureRootIsScheduled(root, currentTime) { } // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root) { - // Since we know we're in a React event, we can clear the current +function performConcurrentWorkOnRoot(root, didTimeout) { // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; + currentEventTransitionLane = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { throw Error("Should not already be working."); @@ -18113,24 +19168,22 @@ function performConcurrentWorkOnRoot(root) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; + } // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + + if (didTimeout) { + // Something expired. Flush synchronously until there's no expired + // work left. + markRootExpired(root, lanes); // This will schedule a synchronous callback. + + ensureRootIsScheduled(root, now()); + return null; } var exitStatus = renderRootConcurrent(root, lanes); - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack(root, NoLanes); - } else if (exitStatus !== RootIncomplete) { + if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. @@ -18322,26 +19375,9 @@ function performSyncWorkOnRoot(root) { // rendering it before rendering the rest of the expired work. lanes = workInProgressRootRenderLanes; exitStatus = renderRootSync(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // Note that this only happens when part of the tree is rendered - // concurrently. If the whole tree is rendered synchronously, then there - // are no interleaved events. - lanes = getNextLanes(root, lanes); - exitStatus = renderRootSync(root, lanes); - } } else { - lanes = getNextLanes(root, NoLanes); + lanes = getNextLanes(root, NoLanes); // Because we don't cancel synchronous tasks, sometimes more than one + exitStatus = renderRootSync(root, lanes); } @@ -18419,7 +19455,7 @@ function flushSync(fn, a) { { try { if (fn) { - return runWithPriority(ImmediatePriority$1, fn.bind(null, a)); + return runWithPriority(ImmediatePriority, fn.bind(null, a)); } else { return undefined; } @@ -18475,6 +19511,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootSkippedLanes = NoLanes; workInProgressRootUpdatedLanes = NoLanes; workInProgressRootPingedLanes = NoLanes; + enqueueInterleavedUpdates(); { spawnedWorkDuringRender = null; @@ -18798,47 +19835,6 @@ function completeUnitOfWork(unitOfWork) { workInProgress = next; return; } - - resetChildLanes(completedWork); - - if ( - returnFiber !== null && // Do not append effects to parents if a sibling failed to complete - (returnFiber.flags & Incomplete) === NoFlags - ) { - // Append all the effects of the subtree and this fiber onto the effect - // list of the parent. The completion order of the children affects the - // side-effect order. - if (returnFiber.firstEffect === null) { - returnFiber.firstEffect = completedWork.firstEffect; - } - - if (completedWork.lastEffect !== null) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork.firstEffect; - } - - returnFiber.lastEffect = completedWork.lastEffect; - } // If this fiber had side-effects, we append it AFTER the children's - // side-effects. We can perform certain side-effects earlier if needed, - // by doing multiple passes over the effect list. We don't want to - // schedule our own side-effect on our own list because if end up - // reusing children we'll schedule this effect onto itself since we're - // at the end. - - var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect - // list. PerformedWork effect is read by React DevTools but shouldn't be - // committed. - - if (flags > PerformedWork) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork; - } else { - returnFiber.firstEffect = completedWork; - } - - returnFiber.lastEffect = completedWork; - } - } } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -18871,9 +19867,10 @@ function completeUnitOfWork(unitOfWork) { } if (returnFiber !== null) { - // Mark the parent fiber as incomplete and clear its effect list. - returnFiber.firstEffect = returnFiber.lastEffect = null; + // Mark the parent fiber as incomplete and clear its subtree flags. returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags; + returnFiber.deletions = null; } } @@ -18895,88 +19892,10 @@ function completeUnitOfWork(unitOfWork) { } } -function resetChildLanes(completedWork) { - if ( - // TODO: Move this check out of the hot path by moving `resetChildLanes` - // to switch statement in `completeWork`. - (completedWork.tag === LegacyHiddenComponent || - completedWork.tag === OffscreenComponent) && - completedWork.memoizedState !== null && - !includesSomeLane(subtreeRenderLanes, OffscreenLane) && - (completedWork.mode & ConcurrentMode) !== NoLanes - ) { - // The children of this component are hidden. Don't bubble their - // expiration times. - return; - } - - var newChildLanes = NoLanes; // 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; // 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. - - var shouldBubbleActualDurations = - completedWork.alternate === null || - completedWork.child !== completedWork.alternate.child; - var child = completedWork.child; - - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - - if (shouldBubbleActualDurations) { - actualDuration += child.actualDuration; - } - - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - var isTimedOutSuspense = - completedWork.tag === SuspenseComponent && - completedWork.memoizedState !== null; - - if (isTimedOutSuspense) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var primaryChildFragment = completedWork.child; - - if (primaryChildFragment !== null) { - treeBaseDuration -= primaryChildFragment.treeBaseDuration; - } - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; - - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - _child = _child.sibling; - } - } - - completedWork.childLanes = newChildLanes; -} - function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); runWithPriority( - ImmediatePriority$1, + ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); return null; @@ -19016,7 +19935,8 @@ function commitRootImpl(root, renderPriorityLevel) { } // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. - root.callbackNode = null; // Update the first and last pending times on this root. The new first + root.callbackNode = null; + root.callbackPriority = NoLanePriority; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); @@ -19038,90 +19958,62 @@ function commitRootImpl(root, renderPriorityLevel) { workInProgressRoot = null; workInProgress = null; workInProgressRootRenderLanes = NoLanes; - } // Get the list of effects. - - var firstEffect; - - if (finishedWork.flags > PerformedWork) { - // A fiber's effect list consists only of its children, not itself. So if - // the root has an effect, we need to add it to the end of the list. The - // resulting list is the set that would belong to the root's parent, if it - // had one; that is, all the effects in the tree including the root. - if (finishedWork.lastEffect !== null) { - finishedWork.lastEffect.nextEffect = finishedWork; - firstEffect = finishedWork.firstEffect; - } else { - firstEffect = finishedWork; - } - } else { - // There is no effect on the root. - firstEffect = finishedWork.firstEffect; - } + } // If there are pending passive effects, schedule a callback to process them. + // Do this as early as possible, so it is queued before anything else that + // might get scheduled in the commit phase. (See #16714.) + // TODO: Delete all other places that schedule the passive effect callback + // They're redundant. - if (firstEffect !== null) { + if ( + (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || + (finishedWork.flags & PassiveMask) !== NoFlags + ) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + }); + } + } // Check if there are any effects in the whole tree. + // TODO: This is left over from the effect list implementation, where we had + // to check for the existence of `firstEffect` to satsify Flow. I think the + // only other reason this optimization exists is because it affects profiling. + // Reconsider whether this is necessary. + + var subtreeHasEffects = + (finishedWork.subtreeFlags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + var rootHasEffect = + (finishedWork.flags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + + if (subtreeHasEffects || rootHasEffect) { var prevExecutionContext = executionContext; executionContext |= CommitContext; var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass - // of the effect list for each phase: all mutation effects come before all - // layout effects, and so on. - // The first phase a "before mutation" phase. We use this phase to read the - // state of the host tree right before we mutate it. This is where - // getSnapshotBeforeUpdate is called. - - focusedInstanceHandle = prepareForCommit(root.containerInfo); - shouldFireAfterActiveInstanceBlur = false; - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitBeforeMutationEffects, null); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); // We no longer need to track the active instance fiber + // of the effect list for each phase: all mutation effects come before all + // layout effects, and so on. + // The first phase a "before mutation" phase. We use this phase to read the + // state of the host tree right before we mutate it. This is where + // getSnapshotBeforeUpdate is called. - focusedInstanceHandle = null; + var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects( + root, + finishedWork + ); { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); - } // The next phase is the mutation phase, where we mutate the host tree. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback( - null, - commitMutationEffects, - null, - root, - renderPriorityLevel - ); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error = clearCaughtError(); + } - captureCommitPhaseError(nextEffect, _error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); + commitMutationEffects(root, renderPriorityLevel, finishedWork); resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after // the mutation phase, so that the previous tree is still current during @@ -19129,29 +20021,8 @@ function commitRootImpl(root, renderPriorityLevel) { // work is current during componentDidMount/Update. root.current = finishedWork; // The next phase is the layout phase, where we call effects that read - // the host tree after it's been mutated. The idiomatic use case for this is - // layout, but class component lifecycles also fire here for legacy reasons. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error2 = clearCaughtError(); - - captureCommitPhaseError(nextEffect, _error2); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); - nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an + commitLayoutEffects(finishedWork, root, lanes); // opportunity to paint. requestPaint(); @@ -19181,22 +20052,6 @@ function commitRootImpl(root, renderPriorityLevel) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; pendingPassiveEffectsRenderPriority = renderPriorityLevel; - } else { - // We are done with the effect chain at this point so let's clear the - // nextEffect pointers to assist with GC. If we have passive effects, we'll - // clear this in flushPassiveEffects. - nextEffect = firstEffect; - - while (nextEffect !== null) { - var nextNextEffect = nextEffect.nextEffect; - nextEffect.nextEffect = null; - - if (nextEffect.flags & Deletion) { - detachFiberAfterEffects(nextEffect); - } - - nextEffect = nextNextEffect; - } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root @@ -19234,9 +20089,9 @@ function commitRootImpl(root, renderPriorityLevel) { } } - if (remainingLanes === SyncLane) { - // Count the number of times the root synchronously re-renders without + if (includesSomeLane(remainingLanes, SyncLane)) { // finishing. If there are too many, it indicates an infinite update loop. + if (root === rootWithNestedUpdates) { nestedUpdateCount++; } else { @@ -19254,9 +20109,9 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var _error3 = firstUncaughtError; + var error = firstUncaughtError; firstUncaughtError = null; - throw _error3; + throw error; } if ((executionContext & LegacyUnbatchedContext) !== NoContext) { @@ -19272,156 +20127,14 @@ function commitRootImpl(root, renderPriorityLevel) { return null; } -function commitBeforeMutationEffects() { - while (nextEffect !== null) { - var current = nextEffect.alternate; - - if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { - if ((nextEffect.flags & Deletion) !== NoFlags) { - if (doesFiberContain(nextEffect, focusedInstanceHandle)) { - shouldFireAfterActiveInstanceBlur = true; - } - } else { - // TODO: Move this out of the hot path using a dedicated effect tag. - if ( - nextEffect.tag === SuspenseComponent && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) - ) { - shouldFireAfterActiveInstanceBlur = true; - } - } - } - - var flags = nextEffect.flags; - - if ((flags & Snapshot) !== NoFlags) { - setCurrentFiber(nextEffect); - commitBeforeMutationLifeCycles(current, nextEffect); - resetCurrentFiber(); - } - - if ((flags & Passive) !== NoFlags) { - // If there are passive effects, schedule a callback to flush at - // the earliest opportunity. - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } - } - - nextEffect = nextEffect.nextEffect; - } -} - -function commitMutationEffects(root, renderPriorityLevel) { - // TODO: Should probably move the bulk of this function to commitWork. - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & ContentReset) { - commitResetTextContent(nextEffect); - } - - if (flags & Ref) { - var current = nextEffect.alternate; - - if (current !== null) { - commitDetachRef(current); - } - } // 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 | Deletion | Hydrating); - - switch (primaryFlags) { - case Placement: { - commitPlacement(nextEffect); // 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. - - nextEffect.flags &= ~Placement; - break; - } - - case PlacementAndUpdate: { - // Placement - commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. - - nextEffect.flags &= ~Placement; // Update - - var _current = nextEffect.alternate; - commitWork(_current, nextEffect); - break; - } - - case Hydrating: { - nextEffect.flags &= ~Hydrating; - break; - } - - case HydratingAndUpdate: { - nextEffect.flags &= ~Hydrating; // Update - - var _current2 = nextEffect.alternate; - commitWork(_current2, nextEffect); - break; - } - - case Update: { - var _current3 = nextEffect.alternate; - commitWork(_current3, nextEffect); - break; - } - - case Deletion: { - commitDeletion(root, nextEffect); - break; - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } -} - -function commitLayoutEffects(root, committedLanes) { - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & (Update | Callback)) { - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); - } - - { - if (flags & Ref) { - commitAttachRef(nextEffect); - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } -} - function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { + if (pendingPassiveEffectsRenderPriority !== NoPriority) { var priorityLevel = - pendingPassiveEffectsRenderPriority > NormalPriority$1 - ? NormalPriority$1 + pendingPassiveEffectsRenderPriority > NormalPriority + ? NormalPriority : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoPriority$1; + pendingPassiveEffectsRenderPriority = NoPriority; { return runWithPriority(priorityLevel, flushPassiveEffectsImpl); @@ -19430,42 +20143,6 @@ function flushPassiveEffects() { return false; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - - { - fiber.flags |= PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags |= PassiveUnmountPendingDev; - } - } - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} - -function invokePassiveEffectCreate(effect) { - var create = effect.create; - effect.destroy = create(); -} function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { @@ -19487,97 +20164,9 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called - // before ANY passive effect create functions are called. - // Otherwise effects in sibling components might interfere with each other. - // e.g. a destroy function in one component may unintentionally override a ref - // value set by a create function in another component. - // Layout effects have the same constraint. - // First pass: Destroy stale passive effects. - - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - - for (var i = 0; i < unmountEffects.length; i += 2) { - var _effect = unmountEffects[i]; - var fiber = unmountEffects[i + 1]; - var destroy = _effect.destroy; - _effect.destroy = undefined; - - { - fiber.flags &= ~PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags &= ~PassiveUnmountPendingDev; - } - } - - if (typeof destroy === "function") { - { - setCurrentFiber(fiber); - - { - invokeGuardedCallback(null, destroy, null); - } - - if (hasCaughtError()) { - if (!(fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(fiber, error); - } - - resetCurrentFiber(); - } - } - } // Second pass: Create new passive effects. - - var mountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - - for (var _i = 0; _i < mountEffects.length; _i += 2) { - var _effect2 = mountEffects[_i]; - var _fiber = mountEffects[_i + 1]; - - { - setCurrentFiber(_fiber); - - { - invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); - } - - if (hasCaughtError()) { - if (!(_fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var _error4 = clearCaughtError(); - - captureCommitPhaseError(_fiber, _error4); - } - - resetCurrentFiber(); - } - } // Note: This currently assumes there are no passive effects on the root fiber - // because the root is not part of its own effect list. - // This could change in the future. - - var effect = root.current.firstEffect; - - while (effect !== null) { - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC - - effect.nextEffect = null; - - if (effect.flags & Deletion) { - detachFiberAfterEffects(effect); - } - - effect = nextNextEffect; - } + var prevInteractions = pushInteractions(root); + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects { popInteractions(prevInteractions); @@ -19634,19 +20223,23 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); return; } - var fiber = sourceFiber.return; + var fiber = null; + + { + fiber = sourceFiber.return; + } while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -19657,7 +20250,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$1, sourceFiber); var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); enqueueUpdate(fiber, update); var eventTime = requestEventTime(); @@ -19667,24 +20260,6 @@ function captureCommitPhaseError(sourceFiber, error) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, SyncLane); - } else { - // This component has already been unmounted. - // We can't schedule any follow up work for the root because the fiber is already unmounted, - // but we can still call the log-only boundary so the error isn't swallowed. - // - // TODO This is only a temporary bandaid for the old reconciler fork. - // We can delete this special case once the new fork is merged. - if ( - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance) - ) { - try { - instance.componentDidCatch(error, errorInfo); - } catch (errorToIgnore) { - // TODO Ignore this error? Rethrow it? - // This is kind of an edge case. - } - } } return; @@ -19693,6 +20268,22 @@ function captureCommitPhaseError(sourceFiber, error) { fiber = fiber.return; } + + { + // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning + // will fire for errors that are thrown by destroy functions inside deleted + // trees. What it should instead do is propagate the error to the parent of + // the deleted tree. In the meantime, do not add this warning to the + // allowlist; this is only for our internal use. + error( + "Internal React error: Attempted to capture a commit phase error " + + "inside a detached tree. This indicates a bug in React. Likely " + + "causes include deleting the same fiber more than once, committing an " + + "already-finished tree, or an inconsistent return pointer.\n\n" + + "Error message:\n\n%s", + error$1 + ); + } } function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; @@ -19745,6 +20336,8 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { // suspended it has resolved, which means at least part of the tree was // likely unblocked. Try rendering again, at a new expiration time. if (retryLane === NoLane) { + // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? retryLane = requestRetryLane(boundaryFiber); } // TODO: Special case idle priority? @@ -19913,11 +20506,29 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } // If there are pending passive effects unmounts for this Fiber, - // we can assume that they would have prevented this update. + } - if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { - return; + if ((fiber.flags & PassiveStatic) !== NoFlags) { + var updateQueue = fiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if (effect.destroy !== undefined) { + if ((effect.tag & Passive$1) !== NoFlags$1) { + return; + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. @@ -20005,14 +20616,23 @@ var beginWork$1; invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); if (hasCaughtError()) { - var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. - // Rethrow this error instead of the original one. + var replayError = clearCaughtError(); - throw replayError; - } else { - // This branch is reachable if the render phase is impure. - throw originalError; - } + if ( + typeof replayError === "object" && + replayError !== null && + replayError._suppressLogging && + typeof originalError === "object" && + originalError !== null && + !originalError._suppressLogging + ) { + // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. + originalError._suppressLogging = true; + } + } // We always throw the original error in case the second render pass is not idempotent. + // This can happen if a memoized function or CommonJS module doesn't throw after first invokation. + + throw originalError; } }; } @@ -20101,7 +20721,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { "act(() => ...);\n\n" + "// for react-test-renderer:\n" + // Break up imports to avoid accidentally parsing them as dependencies. "import TestRenderer fr" + - "om react-test-renderer';\n" + + "om 'react-test-renderer';\n" + "const {act} = TestRenderer;\n" + "// ...\n" + "act(() => ...);" @@ -20119,7 +20739,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { if ( - (fiber.mode & StrictMode) !== NoMode && + (fiber.mode & StrictLegacyMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { @@ -20299,7 +20919,7 @@ function startWorkOnPendingInteractions(root, lanes) { subscriber.onWorkStarted(interactions, threadID); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } @@ -20321,7 +20941,7 @@ function finishPendingInteractions(root, committedLanes) { } } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } finally { @@ -20343,7 +20963,7 @@ function finishPendingInteractions(root, committedLanes) { subscriber.onInteractionScheduledWorkCompleted(interaction); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } @@ -20362,11 +20982,6 @@ function shouldForceFlushFallbacksInDEV() { var actingUpdatesScopeDepth = 0; -function detachFiberAfterEffects(fiber) { - fiber.sibling = null; - fiber.stateNode = null; -} - var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. var failedBoundaries = null; @@ -20843,9 +21458,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.mode = mode; // Effects this.flags = NoFlags; - this.nextEffect = null; - this.firstEffect = null; - this.lastEffect = null; + this.subtreeFlags = NoFlags; + this.deletions = null; this.lanes = NoLanes; this.childLanes = NoLanes; this.alternate = null; @@ -20972,11 +21586,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.type = current.type; // We already have an alternate. // Reset the effect tag. - workInProgress.flags = NoFlags; // The effect list is no longer valid. + workInProgress.flags = NoFlags; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; { // We intentionally reset, rather than copy, actualDuration & actualStartTime. @@ -20986,8 +21599,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; } - } + } // Reset all effects except static ones. + // Static effects are not specific to a render. + workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -21044,13 +21659,10 @@ function resetWorkInProgress(workInProgress, renderLanes) { // when they should be reading from current and writing to workInProgress. // We assume pendingProps, index, key, ref, return are still untouched to // avoid doing another reconciliation. - // Reset the effect tag but keep any Placement tags, since that's something + // Reset the effect flags but keep any Placement tags, since that's something // that child fiber is setting, not the reconciliation. - workInProgress.flags &= Placement; // The effect list is no longer valid. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; var current = workInProgress.alternate; if (current === null) { @@ -21058,6 +21670,7 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = NoLanes; workInProgress.lanes = renderLanes; workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags; workInProgress.memoizedProps = null; workInProgress.memoizedState = null; workInProgress.updateQueue = null; @@ -21074,7 +21687,12 @@ function resetWorkInProgress(workInProgress, renderLanes) { // Reset to the cloned values that createWorkInProgress would've. workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; - workInProgress.child = current.child; + workInProgress.child = current.child; // TODO: `subtreeFlags` should be reset to NoFlags, like we do in + // `createWorkInProgress`. Nothing reads this until the complete phase, + // currently, but it might in the future, and we should be consistent. + + workInProgress.subtreeFlags = current.subtreeFlags; + workInProgress.deletions = null; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. @@ -21101,13 +21719,33 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag) { +function createHostRootFiber(tag, strictModeLevelOverride) { var mode; if (tag === ConcurrentRoot) { - mode = ConcurrentMode | BlockingMode | StrictMode; + mode = ConcurrentMode | BlockingMode; + + if (strictModeLevelOverride !== null) { + if (strictModeLevelOverride >= 1) { + mode |= StrictLegacyMode; + } + } else { + { + mode |= StrictLegacyMode; + } + } } else if (tag === BlockingRoot) { - mode = BlockingMode | StrictMode; + mode = BlockingMode; + + if (strictModeLevelOverride !== null) { + if (strictModeLevelOverride >= 1) { + mode |= StrictLegacyMode; + } + } else { + { + mode |= StrictLegacyMode; + } + } } else { mode = NoMode; } @@ -21158,8 +21796,16 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: - fiberTag = Mode; - mode |= StrictMode; + fiberTag = Mode; // Legacy strict mode ( without any level prop) defaults to level 1. + + var level = + pendingProps.unstable_level == null ? 1 : pendingProps.unstable_level; // Levels cascade; higher levels inherit all lower level modes. + // It is explicitly not supported to lower a mode with nesting, only to increase it. + + if (level >= 1) { + mode |= StrictLegacyMode; + } + break; case REACT_PROFILER_TYPE: @@ -21181,6 +21827,10 @@ function createFiberFromTypeAndProps( // eslint-disable-next-line no-fallthrough + case REACT_CACHE_TYPE: + + // eslint-disable-next-line no-fallthrough + default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -21409,9 +22059,8 @@ function assignFiberPropertiesInDEV(target, source) { target.dependencies = source.dependencies; target.mode = source.mode; target.flags = source.flags; - target.nextEffect = source.nextEffect; - target.firstEffect = source.firstEffect; - target.lastEffect = source.lastEffect; + target.subtreeFlags = source.subtreeFlags; + target.deletions = source.deletions; target.lanes = source.lanes; target.childLanes = source.childLanes; target.alternate = source.alternate; @@ -21478,13 +22127,27 @@ function FiberRootNode(containerInfo, tag, hydrate) { } } -function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { +function createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride +) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag); + var uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + + { + var _initialState = { + element: null + }; + uninitializedFiber.memoizedState = _initialState; + } + initializeUpdateQueue(uninitializedFiber); return root; } @@ -21558,7 +22221,7 @@ function findHostInstanceWithWarning(component, methodName) { return null; } - if (hostFiber.mode & StrictMode) { + if (hostFiber.mode & StrictLegacyMode) { var componentName = getComponentName(fiber.type) || "Component"; if (!didWarnAboutFindNodeInStrictMode[componentName]) { @@ -21568,7 +22231,7 @@ function findHostInstanceWithWarning(component, methodName) { try { setCurrentFiber(hostFiber); - if (fiber.mode & StrictMode) { + if (fiber.mode & StrictLegacyMode) { error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + @@ -21607,8 +22270,20 @@ function findHostInstanceWithWarning(component, methodName) { } } -function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); +function createContainer( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride +) { + return createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride + ); } function updateContainer(element, container, parentComponent, callback) { { @@ -21673,7 +22348,12 @@ function updateContainer(element, container, parentComponent, callback) { } enqueueUpdate(current$1, update); - scheduleUpdateOnFiber(current$1, lane, eventTime); + var root = scheduleUpdateOnFiber(current$1, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, current$1, lane); + } + return lane; } function getPublicRootInstance(container) { @@ -22354,11 +23034,12 @@ function render(element, containerTag, callback) { if (!root) { // TODO (bvaughn): If we decide to keep the wrapper component, // We could create a wrapper for containerTag as well to reduce special casing. - root = createContainer(containerTag, LegacyRoot, false); + root = createContainer(containerTag, LegacyRoot, false, null, null); roots.set(containerTag, root); } - updateContainer(element, root, null, callback); + updateContainer(element, root, null, callback); // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN + return getPublicRootInstance(root); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index ccced617800599..8d91437ab93175 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -919,7 +919,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_222 = { +var injectedNamesToPlugins$jscomp$inline_213 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -954,34 +954,34 @@ var injectedNamesToPlugins$jscomp$inline_222 = { } } }, - isOrderingDirty$jscomp$inline_223 = !1, - pluginName$jscomp$inline_224; -for (pluginName$jscomp$inline_224 in injectedNamesToPlugins$jscomp$inline_222) + isOrderingDirty$jscomp$inline_214 = !1, + pluginName$jscomp$inline_215; +for (pluginName$jscomp$inline_215 in injectedNamesToPlugins$jscomp$inline_213) if ( - injectedNamesToPlugins$jscomp$inline_222.hasOwnProperty( - pluginName$jscomp$inline_224 + injectedNamesToPlugins$jscomp$inline_213.hasOwnProperty( + pluginName$jscomp$inline_215 ) ) { - var pluginModule$jscomp$inline_225 = - injectedNamesToPlugins$jscomp$inline_222[pluginName$jscomp$inline_224]; + var pluginModule$jscomp$inline_216 = + injectedNamesToPlugins$jscomp$inline_213[pluginName$jscomp$inline_215]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_224) || - namesToPlugins[pluginName$jscomp$inline_224] !== - pluginModule$jscomp$inline_225 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_215) || + namesToPlugins[pluginName$jscomp$inline_215] !== + pluginModule$jscomp$inline_216 ) { - if (namesToPlugins[pluginName$jscomp$inline_224]) + if (namesToPlugins[pluginName$jscomp$inline_215]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_224 + + pluginName$jscomp$inline_215 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_224 - ] = pluginModule$jscomp$inline_225; - isOrderingDirty$jscomp$inline_223 = !0; + pluginName$jscomp$inline_215 + ] = pluginModule$jscomp$inline_216; + isOrderingDirty$jscomp$inline_214 = !0; } } -isOrderingDirty$jscomp$inline_223 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_214 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1139,7 +1139,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1158,6 +1159,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1184,6 +1186,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1217,7 +1221,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1305,19 +1309,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1567,60 +1566,382 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { }; } var ReactNativeFiberHostComponent = (function() { - function ReactNativeFiberHostComponent(tag, viewConfig) { - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - } - var _proto = ReactNativeFiberHostComponent.prototype; - _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; - _proto.measure = function(callback) { - ReactNativePrivateInterface.UIManager.measure( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureInWindow = function(callback) { - ReactNativePrivateInterface.UIManager.measureInWindow( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - if ("number" === typeof relativeToNativeNode) - var relativeNode = relativeToNativeNode; - else - relativeToNativeNode._nativeTag && - (relativeNode = relativeToNativeNode._nativeTag); - null != relativeNode && - ReactNativePrivateInterface.UIManager.measureLayout( + function ReactNativeFiberHostComponent(tag, viewConfig) { + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + } + var _proto = ReactNativeFiberHostComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + _proto.measure = function(callback) { + ReactNativePrivateInterface.UIManager.measure( this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - _proto.setNativeProps = function(nativeProps) { - nativeProps = diffProperties( - null, - emptyObject, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( + }; + _proto.measureInWindow = function(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - return ReactNativeFiberHostComponent; -})(); + }; + _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + this._nativeTag, + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + _proto.setNativeProps = function(nativeProps) { + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + this.viewConfig.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + this._nativeTag, + this.viewConfig.uiViewClassName, + nativeProps + ); + }; + return ReactNativeFiberHostComponent; + })(), + Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs = Scheduler_now(), + now = + 1e4 > initialTimeMs + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } +} +var nextTransitionLane = 512, + nextRetryLane = 8388608, + return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return (return_highestLanePriority = 15), 1; + case 2: + return (return_highestLanePriority = 14), 2; + case 4: + return (return_highestLanePriority = 13), 4; + case 8: + return (return_highestLanePriority = 12), 8; + case 16: + return (return_highestLanePriority = 11), 16; + case 32: + return (return_highestLanePriority = 10), 32; + case 64: + return (return_highestLanePriority = 9), 64; + case 128: + return (return_highestLanePriority = 8), 128; + case 256: + return (return_highestLanePriority = 7), 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: + return (return_highestLanePriority = 6), lanes & 8388096; + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return (return_highestLanePriority = 5), lanes & 125829120; + case 134217728: + return (return_highestLanePriority = 4), 134217728; + case 268435456: + return (return_highestLanePriority = 3), 268435456; + case 536870912: + return (return_highestLanePriority = 2), 536870912; + case 1073741824: + return (return_highestLanePriority = 1), 1073741824; + default: + return (return_highestLanePriority = 8), lanes; + } +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + 0 !== expiredLanes + ? ((nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15)) + : ((expiredLanes = pendingLanes & 268435455), + 0 !== expiredLanes + ? ((pendingLanes = expiredLanes & ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))) + : ((pendingLanes &= ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + suspendedLanes = return_highestLanePriority; + if ( + nextLanePriority <= suspendedLanes || + (8 === nextLanePriority && 6 === suspendedLanes) + ) + return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (nextLanePriority = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << nextLanePriority), + (nextLanes |= root[nextLanePriority]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return 8; + case 10: + return 32; + case 8: + return 128; + case 2: + return 536870912; + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$8 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$8; + remainingLanes[index$8] = 0; + eventTimes[index$8] = -1; + root[index$8] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$9 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$9; + (lane & entangledLanes) | (root[index$9] & entangledLanes) && + (root[index$9] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_now$1 = Scheduler.unstable_now; +Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." @@ -1766,296 +2087,17 @@ function invalidateContextProvider(workInProgress, type, didChange) { push(didPerformWorkStackCursor, didChange); } var rendererID = null, - injectedHook = null, - Scheduler_now = Scheduler.unstable_now; -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, - fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; + injectedHook = null; +function onCommitRoot(root) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } + injectedHook.onCommitFiberRoot( + rendererID, + root, + void 0, + 128 === (root.current.flags & 128) + ); + } catch (err) {} } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2135,10 +2177,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue = currentValue; + context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2189,13 +2231,14 @@ function readContext(context, observedBits) { } return context._currentValue; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2221,14 +2264,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2297,111 +2358,110 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2457,7 +2517,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2468,7 +2529,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2478,7 +2540,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2626,24 +2689,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw Error( + throw ((returnFiber = Object.prototype.toString.call(newChild)), + Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) + ("[object Object]" === returnFiber ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : returnFiber) + "). If you meant to render a collection of children, use an array instead." - ); + )); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2675,16 +2736,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2699,7 +2760,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2813,15 +2883,7 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2856,15 +2918,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3070,43 +3124,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + isObject = newChild.type; + if (isObject === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3284,7 +3333,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3436,10 +3485,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3464,22 +3514,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3519,7 +3580,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3549,25 +3610,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$13 = 31 - clz32(lanes), - lane = 1 << index$13; - entanglements[index$13] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3594,6 +3643,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3619,6 +3670,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3667,7 +3720,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3675,10 +3728,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(132096, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3763,33 +3816,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 8388096) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3846,6 +3921,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4021,7 +4098,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4097,14 +4174,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4121,30 +4199,39 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 2)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, current), - null - ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= nextProps; + } else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4154,7 +4241,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4179,7 +4266,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4354,7 +4441,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4362,7 +4449,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4376,7 +4463,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4397,7 +4484,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4441,18 +4528,21 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; +} function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4469,7 +4559,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4481,9 +4573,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), + (workInProgress.lanes = 8388608), current ); renderLanes = createFiberFromOffscreen( @@ -4509,8 +4603,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4537,8 +4634,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4561,7 +4661,7 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren)) : (progressedPrimaryFragment = createFiberFromOffscreen( @@ -4594,13 +4694,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4610,26 +4711,22 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + 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), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4654,8 +4751,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4665,16 +4761,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4683,9 +4777,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4708,7 +4802,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4729,8 +4823,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4752,19 +4845,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4774,25 +4859,23 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } - return null; + return workInProgress.child; } var appendAllChildren, updateHostContainer, @@ -4839,16 +4922,40 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$64 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), + for (var lastTailNode$62 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$62 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$64 + null === lastTailNode$62 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$64.sibling = null); + : (lastTailNode$62.sibling = null); } } +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$63 = completedWork.child; null !== child$63; ) + (newChildLanes |= child$63.lanes | child$63.childLanes), + (subtreeFlags |= child$63.subtreeFlags & 131072), + (subtreeFlags |= child$63.flags & 131072), + (child$63.return = completedWork), + (child$63 = child$63.sibling); + else + for (child$63 = completedWork.child; null !== child$63; ) + (newChildLanes |= child$63.lanes | child$63.childLanes), + (subtreeFlags |= child$63.subtreeFlags), + (subtreeFlags |= child$63.flags), + (child$63.return = completedWork), + (child$63 = child$63.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4862,76 +4969,80 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); 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(); - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); ReactNativePrivateInterface.UIManager.createView( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload ); - rootContainerInstance = new ReactNativeFiberHostComponent( + renderLanes = new ReactNativeFiberHostComponent( current, - renderLanes, + type, workInProgress ); instanceCache.set(current, workInProgress); instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 128); + appendAllChildren(renderLanes, workInProgress, !1, !1); + workInProgress.stateNode = renderLanes; + finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -4951,27 +5062,27 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "Text strings must be rendered within a component." ); - rootContainerInstance = allocateTag(); + renderLanes = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, + renderLanes, "RCTRawText", current, { text: newProps } ); - instanceCache.set(rootContainerInstance, workInProgress); - workInProgress.stateNode = rootContainerInstance; + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -4986,82 +5097,92 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } - if (newProps || rootContainerInstance) workInProgress.flags |= 4; + if (newProps || renderLanes) workInProgress.flags |= 4; + bubbleProperties(workInProgress); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderLanes = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), + (renderLanes = newProps), + (type = current), + (renderLanes.flags &= 131074), + (updatePayload = renderLanes.alternate), null === updatePayload - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = renderLanes), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null)) - : ((rootContainerInstance.childLanes = - updatePayload.childLanes), - (rootContainerInstance.lanes = updatePayload.lanes), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = + ? ((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 = updatePayload.subtreeFlags), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = + (renderLanes.memoizedState = updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (rootContainerInstance.type = updatePayload.type), - (renderLanes = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderLanes + (renderLanes.updateQueue = updatePayload.updateQueue), + (renderLanes.type = updatePayload.type), + (type = updatePayload.dependencies), + (renderLanes.dependencies = + null === type ? null : { - lanes: renderLanes.lanes, - firstContext: renderLanes.firstContext + lanes: type.lanes, + firstContext: type.firstContext })), (newProps = newProps.sibling); push( @@ -5072,78 +5193,74 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + 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) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 2)) || + bubbleProperties(workInProgress), null ); } @@ -5158,8 +5275,8 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null; case 3: popHostContainer(); @@ -5167,11 +5284,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5179,8 +5296,8 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null ); case 19: @@ -5188,10 +5305,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5264,140 +5383,150 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + 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." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - 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." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$81 = finishedRoot.create; - finishedRoot.destroy = create$81(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$81 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$81; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$81 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$81, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$80 = effect.create; + effect.destroy = create$80(); } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - 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 hideOrUnhideAllChildren(finishedWork, isHidden) { for (var node = finishedWork; ; ) { @@ -5457,7 +5586,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { node = node.sibling; } } -function commitUnmount(finishedRoot, current) { +function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) try { injectedHook.onCommitFiberUnmount(rendererID, current); @@ -5474,26 +5603,24 @@ function commitUnmount(finishedRoot, current) { ) { var effect = (finishedRoot = finishedRoot.next); do { - var _effect2 = effect, - destroy = _effect2.destroy; - _effect2 = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (_effect2 & 4)) - enqueuePendingPassiveHookEffectUnmount(current, effect); - else { - _effect2 = current; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } + var _effect = effect, + destroy = _effect.destroy; + _effect = _effect.tag; + if (void 0 !== destroy && 0 !== (_effect & 2)) { + _effect = current; + var nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect, nearestMountedAncestor, error); } + } effect = effect.next; } while (effect !== finishedRoot); } break; case 1: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); finishedRoot = current.stateNode; if ("function" === typeof finishedRoot.componentWillUnmount) try { @@ -5501,26 +5628,34 @@ function commitUnmount(finishedRoot, current) { (finishedRoot.state = current.memoizedState), finishedRoot.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError( + current, + nearestMountedAncestor$jscomp$0, + unmountError + ); } break; case 5: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); break; case 4: - unmountHostComponents(finishedRoot, current); + unmountHostComponents( + finishedRoot, + current, + nearestMountedAncestor$jscomp$0 + ); } } -function detachFiberMutation(fiber) { +function detachFiberAfterEffects(fiber) { fiber.alternate = null; fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function isHostParent(fiber) { @@ -5555,7 +5690,7 @@ function commitPlacement(finishedWork) { "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); } - parentFiber.flags & 16 && (parentFiber.flags &= -17); + parentFiber.flags & 32 && (parentFiber.flags &= -33); a: b: for (parentFiber = finishedWork; ; ) { for (; null === parentFiber.sibling; ) { if (null === parentFiber.return || isHostParent(parentFiber.return)) { @@ -5671,7 +5806,11 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents(finishedRoot$jscomp$0, current) { +function unmountHostComponents( + finishedRoot$jscomp$0, + current, + nearestMountedAncestor$jscomp$0 +) { for ( var node = current, currentParentIsValid = !1, @@ -5709,12 +5848,13 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { a: for ( var finishedRoot = finishedRoot$jscomp$0, root = node, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0, node$jscomp$0 = root; ; ) if ( - (commitUnmount(finishedRoot, node$jscomp$0), + (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) ) (node$jscomp$0.child.return = node$jscomp$0), @@ -5741,18 +5881,18 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { [0] )) : ((finishedRoot = currentParent), - (node$jscomp$0 = node.stateNode), - recursivelyUncacheFiberNode(node$jscomp$0), + (nearestMountedAncestor = node.stateNode), + recursivelyUncacheFiberNode(nearestMountedAncestor), (root = finishedRoot._children), - (node$jscomp$0 = root.indexOf(node$jscomp$0)), - root.splice(node$jscomp$0, 1), + (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), + root.splice(nearestMountedAncestor, 1), ReactNativePrivateInterface.UIManager.manageChildren( finishedRoot._nativeTag, [], [], [], [], - [node$jscomp$0] + [nearestMountedAncestor] )); } else if (4 === node.tag) { if (null !== node.child) { @@ -5763,7 +5903,12 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { continue; } } else if ( - (commitUnmount(finishedRoot$jscomp$0, node), null !== node.child) + (commitUnmount( + finishedRoot$jscomp$0, + node, + nearestMountedAncestor$jscomp$0 + ), + null !== node.child) ) { node.child.return = node; node = node.child; @@ -5785,42 +5930,31 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do - 3 === (effect.tag & 3) && - ((finishedWork = effect.destroy), - (effect.destroy = void 0), - void 0 !== finishedWork && finishedWork()), - (effect = effect.next); - while (effect !== updateQueue); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 1: return; case 5: - updateQueue = finishedWork.stateNode; - if (null != updateQueue) { - effect = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : effect; + 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 = updateQueue.viewConfig), - instanceProps.set(updateQueue._nativeTag, effect), - (effect = diffProperties( + ((finishedWork = instance.viewConfig), + instanceProps.set(instance._nativeTag, newProps), + (newProps = diffProperties( null, current, - effect, + newProps, finishedWork.validAttributes )), - null != effect && + null != newProps && ReactNativePrivateInterface.UIManager.updateView( - updateQueue._nativeTag, + instance._nativeTag, finishedWork.uiViewClassName, - effect + newProps )); } return; @@ -5858,32 +5992,207 @@ function commitWork(current, finishedWork) { ); 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." - ); + 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; + if (null !== wakeables) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + null === retryCache && + (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); + wakeables.forEach(function(wakeable) { + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + retryCache.has(wakeable) || + (retryCache.add(wakeable), wakeable.then(retry, retry)); + }); + } +} +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + renderPriorityLevel = nextEffect; + firstChild = renderPriorityLevel.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) { + var childToDelete = firstChild[i]; + try { + unmountHostComponents(root, childToDelete, renderPriorityLevel); + var alternate = childToDelete.alternate; + childToDelete.return = null; + null !== alternate && (alternate.return = null); + } catch (error) { + captureCommitPhaseError(childToDelete, renderPriorityLevel, error); + } + } + firstChild = renderPriorityLevel.child; + if (0 !== (renderPriorityLevel.subtreeFlags & 6454) && null !== firstChild) + (firstChild.return = renderPriorityLevel), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + renderPriorityLevel = nextEffect; + try { + var flags = renderPriorityLevel.flags; + if (flags & 256) { + var current = renderPriorityLevel.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + commitPlacement(renderPriorityLevel); + renderPriorityLevel.flags &= -3; + break; + case 6: + commitPlacement(renderPriorityLevel); + renderPriorityLevel.flags &= -3; + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + break; + case 2048: + renderPriorityLevel.flags &= -2049; + break; + case 2052: + renderPriorityLevel.flags &= -2049; + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + break; + case 4: + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + } + } catch (error) { + captureCommitPhaseError( + renderPriorityLevel, + renderPriorityLevel.return, + error + ); + } + firstChild = renderPriorityLevel.sibling; + if (null !== firstChild) { + firstChild.return = renderPriorityLevel.return; + nextEffect = firstChild; + break; + } + nextEffect = renderPriorityLevel.return; + } + } } -function attachSuspenseRetryListeners(finishedWork) { - var wakeables = finishedWork.updateQueue; - if (null !== wakeables) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - wakeables.forEach(function(wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - retryCache.has(wakeable) || - (retryCache.add(wakeable), wakeable.then(retry, retry)); - }); +function commitLayoutEffects(finishedWork) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; + try { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, firstChild); + break; + case 1: + var instance = firstChild.stateNode; + if (firstChild.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + firstChild.elementType === firstChild.type + ? current.memoizedProps + : resolveDefaultProps( + firstChild.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = firstChild.updateQueue; + null !== updateQueue && + commitUpdateQueue(firstChild, updateQueue, instance); + break; + case 3: + var updateQueue$81 = firstChild.updateQueue; + if (null !== updateQueue$81) { + current = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { + case 5: + current = firstChild.child.stateNode; + break; + case 1: + current = firstChild.child.stateNode; + } + commitUpdateQueue(firstChild, updateQueue$81, current); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + 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." + ); + } + if (firstChild.flags & 256) { + current = void 0; + var ref = firstChild.ref; + if (null !== ref) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { + case 5: + current = instance$jscomp$0; + break; + default: + current = instance$jscomp$0; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + } + if (firstChild === fiber) { + nextEffect = null; + break; + } + current = firstChild.sibling; + if (null !== current) { + current.return = firstChild.return; + nextEffect = current; + break; + } + nextEffect = firstChild.return; + } } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; -} var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, @@ -5895,30 +6204,22 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -5928,30 +6229,22 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } + if (0 === (fiber & 1)) return 1; + if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) + ? (fiber = findUpdateLane(12)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); + (fiber = findUpdateLane(fiber))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -5982,7 +6275,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime)); - mostRecentlyUpdatedRoot = fiber; + return fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6007,15 +6300,15 @@ function ensureRootIsScheduled(root, currentTime) { 0 < lanes; ) { - var index$7 = 31 - clz32(lanes), - lane = 1 << index$7, - expirationTime = expirationTimes[index$7]; + var index$6 = 31 - clz32(lanes), + lane = 1 << index$6, + expirationTime = expirationTimes[index$6]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { expirationTime = currentTime; getHighestPriorityLanes(lane); var priority = return_highestLanePriority; - expirationTimes[index$7] = + expirationTimes[index$6] = 10 <= priority ? expirationTime + 250 : 6 <= priority @@ -6030,45 +6323,42 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && + 0 === suspendedLanes + ? (null !== existingCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); - } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); - root.callbackPriority = currentTime; - root.callbackNode = existingCallbackNode; - } -} -function performConcurrentWorkOnRoot(root) { + (root.callbackPriority = 0)) + : root.callbackPriority !== currentTime && + (null != existingCallbackNode && + Scheduler_cancelCallback(existingCallbackNode), + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = null)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority( + currentTime + )), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))), + (root.callbackPriority = currentTime), + (root.callbackNode = existingCallbackNode)); +} +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; + currentEventTransitionLane = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -6079,16 +6369,22 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - var exitStatus = lanes; + if (didTimeout) + return ( + (root.expiredLanes |= lanes & root.pendingLanes), + ensureRootIsScheduled(root, now()), + null + ); + didTimeout = lanes; var prevExecutionContext = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( workInProgressRoot !== root || - workInProgressRootRenderLanes !== exitStatus + workInProgressRootRenderLanes !== didTimeout ) (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, exitStatus); + prepareFreshStack(root, didTimeout); do try { workLoopConcurrent(); @@ -6101,19 +6397,17 @@ function performConcurrentWorkOnRoot(root) { ReactCurrentDispatcher$2.current = prevDispatcher; executionContext = prevExecutionContext; null !== workInProgress - ? (exitStatus = 0) + ? (didTimeout = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && + (didTimeout = workInProgressRootExitStatus)); + if (0 !== didTimeout) { + 2 === didTimeout && ((executionContext |= 64), root.hydrate && (root.hydrate = !1), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6121,7 +6415,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6131,9 +6425,9 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 125829120) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; prevExecutionContext = root.suspendedLanes; @@ -6144,7 +6438,7 @@ function performConcurrentWorkOnRoot(root) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -6152,13 +6446,13 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; + if ((lanes & 8388096) === lanes) break; + didTimeout = root.eventTimes; for (prevExecutionContext = -1; 0 < lanes; ) { - var index$6 = 31 - clz32(lanes); - prevDispatcher = 1 << index$6; - index$6 = exitStatus[index$6]; - index$6 > prevExecutionContext && (prevExecutionContext = index$6); + var index$5 = 31 - clz32(lanes); + prevDispatcher = 1 << index$5; + index$5 = didTimeout[index$5]; + index$5 > prevExecutionContext && (prevExecutionContext = index$5); lanes &= ~prevDispatcher; } lanes = prevExecutionContext; @@ -6204,9 +6498,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$11 = 31 - clz32(suspendedLanes), - lane = 1 << index$11; - root[index$11] = -1; + var index$7 = 31 - clz32(suspendedLanes), + lane = 1 << index$7; + root[index$7] = -1; suspendedLanes &= ~lane; } } @@ -6214,17 +6508,12 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( + var lanes = root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); + ? workInProgressRootRenderLanes + : getNextLanes(root, 0); + var exitStatus = renderRootSync(root, lanes); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6243,11 +6532,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6287,7 +6571,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6297,10 +6581,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6336,15 +6639,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6355,15 +6661,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$76 = returnFiber; + workInProgress$75 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$76.tag)) { - var nextState = workInProgress$76.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$75.tag)) { + var nextState = workInProgress$75.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$76.memoizedProps; + var props = workInProgress$75.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6375,16 +6681,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$76.updateQueue; + var wakeables = workInProgress$75.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$76.updateQueue = updateQueue; + workInProgress$75.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$76.mode & 2)) { - workInProgress$76.flags |= 64; - sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + if ( + 0 === (workInProgress$75.mode & 1) && + workInProgress$75 !== returnFiber + ) { + workInProgress$75.flags |= 128; + sourceFiber.flags |= 65536; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6415,12 +6724,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$76.flags |= 8192; - workInProgress$76.lanes = thrownValue; + workInProgress$75.flags |= 16384; + workInProgress$75.lanes = thrownValue; break a; } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$75 = workInProgress$75.return; + } while (null !== workInProgress$75); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6429,47 +6738,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$76 = returnFiber; + workInProgress$75 = returnFiber; do { - switch (workInProgress$76.tag) { + switch (workInProgress$75.tag) { case 3: root = value; - workInProgress$76.flags |= 8192; + workInProgress$75.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$77 = createRootErrorUpdate( - workInProgress$76, + workInProgress$75.lanes |= thrownValue; + var update$76 = createRootErrorUpdate( + workInProgress$75, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$77); + enqueueCapturedUpdate(workInProgress$75, update$76); break a; case 1: root = value; - var ctor = workInProgress$76.type, - instance = workInProgress$76.stateNode; + var ctor = workInProgress$75.type, + instance = workInProgress$75.stateNode; if ( - 0 === (workInProgress$76.flags & 64) && + 0 === (workInProgress$75.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$76.flags |= 8192; + workInProgress$75.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$80 = createClassErrorUpdate( - workInProgress$76, + workInProgress$75.lanes |= thrownValue; + var update$79 = createClassErrorUpdate( + workInProgress$75, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$80); + enqueueCapturedUpdate(workInProgress$75, update$79); break a; } } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$75 = workInProgress$75.return; + } while (null !== workInProgress$75); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6530,47 +6839,25 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - current = completeWork(current, completedWork, subtreeRenderLanes); - if (null !== current) { - workInProgress = current; - return; - } - current = completedWork; + if (0 === (completedWork.flags & 8192)) { if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) + ((current = completeWork(current, completedWork, subtreeRenderLanes)), + null !== current) ) { - for (var newChildLanes = 0, child = current.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (child = child.sibling); - current.childLanes = newChildLanes; + workInProgress = current; + return; } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6591,7 +6878,8 @@ function commitRootImpl(root, renderPriorityLevel) { while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 48)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork; + var finishedWork = root.finishedWork, + lanes = root.finishedLanes; if (null === finishedWork) return null; root.finishedWork = null; root.finishedLanes = 0; @@ -6600,174 +6888,48 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$12 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$12; - remainingLanes$jscomp$0[index$12] = 0; - eventTimes[index$12] = -1; - expirationTimes[index$12] = -1; - noLongerPendingLanes &= ~lane; - } + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && + 0 === (remainingLanes & 8) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; - executionContext |= 32; - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; - nextEffect = remainingLanes; - do - try { - for (eventTimes = root; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - break; - case 6: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - expirationTimes = nextEffect; - unmountHostComponents(eventTimes, expirationTimes); - var alternate = expirationTimes.alternate; - detachFiberMutation(expirationTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$88) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$88); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance; - break; - default: - current = instance; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$89) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$89); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; - requestPaint(); - executionContext = remainingLanes$jscomp$0; - } else root.current = finishedWork; - if (rootDoesHavePassiveEffects) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (renderPriorityLevel = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((flags$jscomp$0 = nextEffect), - (flags$jscomp$0.sibling = null), - (flags$jscomp$0.stateNode = null)), - (nextEffect = renderPriorityLevel); + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + 0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes + ? ((remainingLanes = executionContext), + (executionContext |= 32), + (ReactCurrentOwner$2.current = null), + commitBeforeMutationEffects(root, finishedWork), + commitMutationEffects(root, renderPriorityLevel, finishedWork), + (root.current = finishedWork), + commitLayoutEffects(finishedWork, root, lanes), + requestPaint(), + (executionContext = remainingLanes)) + : (root.current = finishedWork); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsRenderPriority = renderPriorityLevel)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - 1 === remainingLanes + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - void 0, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6778,30 +6940,6 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6813,24 +6951,6 @@ function flushPassiveEffects() { } return !1; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; @@ -6839,40 +6959,103 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$94 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$94.destroy; - effect$94.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); + for (nextEffect = root.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + if (fiber$jscomp$0 === fiberToDelete) { + nextEffect = null; + break; + } + child$jscomp$0 = fiber$jscomp$0.sibling; + if (null !== child$jscomp$0) { + child$jscomp$0.return = fiber$jscomp$0.return; + nextEffect = child$jscomp$0; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } + fiber$jscomp$0 = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); + null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); + } + nextEffect = fiber; } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$94 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; - try { - var create$98 = effect$94.create; - effect$94.destroy = create$98(); - } catch (error$99) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$99); } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + a: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + child = fiber.sibling; + if (null !== child) { + child.return = fiber.return; + nextEffect = child; + break a; + } + nextEffect = fiber.return; + } } - for (create$98 = root.current.firstEffect; null !== create$98; ) - (root = create$98.nextEffect), - (create$98.nextEffect = null), - create$98.flags & 8 && - ((create$98.sibling = null), (create$98.stateNode = null)), - (create$98 = root); + for (nextEffect = root = root.current; null !== nextEffect; ) + if ( + ((fiber = nextEffect), + (child = fiber.child), + 0 !== (fiber.subtreeFlags & 1040) && null !== child) + ) + (child.return = fiber), (nextEffect = child); + else + a: for (fiber = root; null !== nextEffect; ) { + child = nextEffect; + if (0 !== (child.flags & 1024)) + try { + switch (child.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, child); + } + } catch (error) { + captureCommitPhaseError(child, child.return, error); + } + if (child === fiber) { + nextEffect = null; + break a; + } + deletions = child.sibling; + if (null !== deletions) { + deletions.return = child.return; + nextEffect = deletions; + break a; + } + nextEffect = child.return; + } executionContext = prevExecutionContext; flushSyncCallbackQueue(); return !0; @@ -6887,42 +7070,50 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { (markRootUpdated(rootFiber, 1, sourceFiber), ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6934,7 +7125,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 125829120) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6947,14 +7138,13 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + 0 === (wakeable & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) + : 0 === (wakeable & 2) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6970,78 +7160,83 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateLanes; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, + if (0 === (renderLanes & updateLanes)) { + didReceiveUpdate = !1; + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer( workInProgress, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + break; + case 10: + updateLanes = workInProgress.type._context; + var nextValue = workInProgress.memoizedProps.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = nextValue; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); + return null !== workInProgress ? workInProgress.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; + case 19: + updateLanes = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; + } + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); + } + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7053,22 +7248,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7078,8 +7273,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7090,9 +7285,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7104,28 +7299,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7134,7 +7329,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7143,7 +7338,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7152,8 +7347,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7161,7 +7356,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7169,32 +7364,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7205,19 +7400,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7257,16 +7451,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7303,27 +7497,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; + nextValue = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue); - context$jscomp$0._currentValue = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = nextValue.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = hasContext; + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = objectIs(oldValue, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits(oldValue, hasContext) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7335,15 +7523,14 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + oldValue = workInProgress.child, + null !== oldValue && (oldValue.return = workInProgress); + null !== oldValue; ) { - var list = context$jscomp$0.dependencies; + var list = oldValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + getDerivedStateFromProps = oldValue.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7353,20 +7540,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (1 === oldValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + oldValue.lanes |= renderLanes; + dependency = oldValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(oldValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7374,16 +7565,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + 10 === oldValue.tag + ? oldValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; + : oldValue.child + : oldValue.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + getDerivedStateFromProps.return = oldValue; else for ( - getDerivedStateFromProps = context$jscomp$0; + getDerivedStateFromProps = oldValue; null !== getDerivedStateFromProps; ) { @@ -7391,20 +7582,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + oldValue = getDerivedStateFromProps.sibling; + if (null !== oldValue) { + oldValue.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = oldValue; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - context$jscomp$0 = getDerivedStateFromProps; + oldValue = getDerivedStateFromProps; } + } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7412,28 +7604,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7451,11 +7643,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7465,8 +7657,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7498,8 +7690,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; } @@ -7537,9 +7729,9 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null)); + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null)); + workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7574,15 +7766,18 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 8; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + 1 <= + (null == pendingProps.unstable_level + ? 1 + : pendingProps.unstable_level) && (mode |= 16); break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 4)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -7769,7 +7964,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7808,10 +8004,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_908 = { + devToolsConfig$jscomp$inline_959 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7826,11 +8022,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1115 = { - bundleType: devToolsConfig$jscomp$inline_908.bundleType, - version: devToolsConfig$jscomp$inline_908.version, - rendererPackageName: devToolsConfig$jscomp$inline_908.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_908.rendererConfig, +var internals$jscomp$inline_1242 = { + bundleType: devToolsConfig$jscomp$inline_959.bundleType, + version: devToolsConfig$jscomp$inline_959.version, + rendererPackageName: devToolsConfig$jscomp$inline_959.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_959.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7845,7 +8041,7 @@ var internals$jscomp$inline_1115 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_908.findFiberByHostInstance || + devToolsConfig$jscomp$inline_959.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -7854,16 +8050,16 @@ var internals$jscomp$inline_1115 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1116 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1243 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1116.isDisabled && - hook$jscomp$inline_1116.supportsFiber + !hook$jscomp$inline_1243.isDisabled && + hook$jscomp$inline_1243.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1116.inject( - internals$jscomp$inline_1115 + (rendererID = hook$jscomp$inline_1243.inject( + internals$jscomp$inline_1242 )), - (injectedHook = hook$jscomp$inline_1116); + (injectedHook = hook$jscomp$inline_1243); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -7912,10 +8108,11 @@ exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = createFiber(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); + var JSCompiler_inline_result = createFiber(3, null, null, 0); + root.current = JSCompiler_inline_result; + JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; + initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 7937b1e922259d..680b703d37e6b2 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -920,7 +920,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_226 = { +var injectedNamesToPlugins$jscomp$inline_219 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -955,34 +955,34 @@ var injectedNamesToPlugins$jscomp$inline_226 = { } } }, - isOrderingDirty$jscomp$inline_227 = !1, - pluginName$jscomp$inline_228; -for (pluginName$jscomp$inline_228 in injectedNamesToPlugins$jscomp$inline_226) + isOrderingDirty$jscomp$inline_220 = !1, + pluginName$jscomp$inline_221; +for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) if ( - injectedNamesToPlugins$jscomp$inline_226.hasOwnProperty( - pluginName$jscomp$inline_228 + injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( + pluginName$jscomp$inline_221 ) ) { - var pluginModule$jscomp$inline_229 = - injectedNamesToPlugins$jscomp$inline_226[pluginName$jscomp$inline_228]; + var pluginModule$jscomp$inline_222 = + injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_228) || - namesToPlugins[pluginName$jscomp$inline_228] !== - pluginModule$jscomp$inline_229 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || + namesToPlugins[pluginName$jscomp$inline_221] !== + pluginModule$jscomp$inline_222 ) { - if (namesToPlugins[pluginName$jscomp$inline_228]) + if (namesToPlugins[pluginName$jscomp$inline_221]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_228 + + pluginName$jscomp$inline_221 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_228 - ] = pluginModule$jscomp$inline_229; - isOrderingDirty$jscomp$inline_227 = !0; + pluginName$jscomp$inline_221 + ] = pluginModule$jscomp$inline_222; + isOrderingDirty$jscomp$inline_220 = !0; } } -isOrderingDirty$jscomp$inline_227 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1140,7 +1140,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1159,6 +1160,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1185,6 +1187,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1218,7 +1222,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1306,19 +1310,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1568,60 +1567,396 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { }; } var ReactNativeFiberHostComponent = (function() { - function ReactNativeFiberHostComponent(tag, viewConfig) { - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - } - var _proto = ReactNativeFiberHostComponent.prototype; - _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; - _proto.measure = function(callback) { - ReactNativePrivateInterface.UIManager.measure( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureInWindow = function(callback) { - ReactNativePrivateInterface.UIManager.measureInWindow( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - if ("number" === typeof relativeToNativeNode) - var relativeNode = relativeToNativeNode; - else - relativeToNativeNode._nativeTag && - (relativeNode = relativeToNativeNode._nativeTag); - null != relativeNode && - ReactNativePrivateInterface.UIManager.measureLayout( + function ReactNativeFiberHostComponent(tag, viewConfig) { + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + } + var _proto = ReactNativeFiberHostComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + _proto.measure = function(callback) { + ReactNativePrivateInterface.UIManager.measure( this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - _proto.setNativeProps = function(nativeProps) { - nativeProps = diffProperties( - null, - emptyObject, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( + }; + _proto.measureInWindow = function(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - return ReactNativeFiberHostComponent; -})(); + }; + _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + this._nativeTag, + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + _proto.setNativeProps = function(nativeProps) { + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + this.viewConfig.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + this._nativeTag, + this.viewConfig.uiViewClassName, + nativeProps + ); + }; + return ReactNativeFiberHostComponent; + })(), + Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +var requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs = Scheduler_now(), + now = + 1e4 > initialTimeMs + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } +} +var nextTransitionLane = 512, + nextRetryLane = 8388608, + return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return (return_highestLanePriority = 15), 1; + case 2: + return (return_highestLanePriority = 14), 2; + case 4: + return (return_highestLanePriority = 13), 4; + case 8: + return (return_highestLanePriority = 12), 8; + case 16: + return (return_highestLanePriority = 11), 16; + case 32: + return (return_highestLanePriority = 10), 32; + case 64: + return (return_highestLanePriority = 9), 64; + case 128: + return (return_highestLanePriority = 8), 128; + case 256: + return (return_highestLanePriority = 7), 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: + return (return_highestLanePriority = 6), lanes & 8388096; + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return (return_highestLanePriority = 5), lanes & 125829120; + case 134217728: + return (return_highestLanePriority = 4), 134217728; + case 268435456: + return (return_highestLanePriority = 3), 268435456; + case 536870912: + return (return_highestLanePriority = 2), 536870912; + case 1073741824: + return (return_highestLanePriority = 1), 1073741824; + default: + return (return_highestLanePriority = 8), lanes; + } +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + 0 !== expiredLanes + ? ((nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15)) + : ((expiredLanes = pendingLanes & 268435455), + 0 !== expiredLanes + ? ((pendingLanes = expiredLanes & ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))) + : ((pendingLanes &= ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + suspendedLanes = return_highestLanePriority; + if ( + nextLanePriority <= suspendedLanes || + (8 === nextLanePriority && 6 === suspendedLanes) + ) + return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (nextLanePriority = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << nextLanePriority), + (nextLanes |= root[nextLanePriority]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return 8; + case 10: + return 32; + case 8: + return 128; + case 2: + return 536870912; + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$8 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$8; + remainingLanes[index$8] = 0; + eventTimes[index$8] = -1; + root[index$8] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$9 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$9; + (lane & entangledLanes) | (root[index$9] & entangledLanes) && + (root[index$9] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_now$1 = Scheduler.unstable_now; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." @@ -1768,310 +2103,17 @@ function invalidateContextProvider(workInProgress, type, didChange) { } var rendererID = null, injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, - Scheduler_now = Scheduler.unstable_now; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function onCommitRoot(root, priorityLevel) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + 128 === (root.current.flags & 128) + ); + } catch (err) {} } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2151,10 +2193,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue = currentValue; + context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2205,13 +2247,14 @@ function readContext(context, observedBits) { } return context._currentValue; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2237,14 +2280,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2313,111 +2374,110 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2473,7 +2533,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2484,7 +2545,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2494,7 +2556,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2642,24 +2705,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw Error( + throw ((returnFiber = Object.prototype.toString.call(newChild)), + Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) + ("[object Object]" === returnFiber ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : returnFiber) + "). If you meant to render a collection of children, use an array instead." - ); + )); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2691,16 +2752,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2715,7 +2776,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2829,15 +2899,7 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2872,15 +2934,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3086,43 +3140,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + isObject = newChild.type; + if (isObject === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3300,7 +3349,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3452,10 +3501,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3480,22 +3530,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3535,7 +3596,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3565,25 +3626,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$13 = 31 - clz32(lanes), - lane = 1 << index$13; - entanglements[index$13] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3610,6 +3659,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3635,6 +3686,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3683,7 +3736,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3691,10 +3744,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(132096, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3779,33 +3832,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 8388096) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3862,6 +3937,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4052,7 +4129,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4128,14 +4205,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4152,31 +4230,40 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 2)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + markSpawnedWork(1073741824), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - markSpawnedWork(1073741824), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, current), - null - ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= nextProps; + } else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4186,7 +4273,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4211,7 +4298,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4386,7 +4473,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4394,7 +4481,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4408,7 +4495,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4429,7 +4516,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4477,18 +4564,21 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; +} function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4505,7 +4595,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4517,10 +4609,12 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608), current ); renderLanes = createFiberFromOffscreen( @@ -4546,8 +4640,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4574,8 +4671,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4598,10 +4698,10 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 8 && + workInProgress.mode & 4 && ((progressedPrimaryFragment.actualDuration = 0), (progressedPrimaryFragment.actualStartTime = -1), (progressedPrimaryFragment.selfBaseDuration = 0), @@ -4636,13 +4736,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4652,33 +4753,27 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + 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 & 8 && + workInProgress.mode & 4 && ((primaryChildren.actualDuration = 0), (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration), - (primaryChildren.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration)), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (primaryChildren.selfBaseDuration = current.selfBaseDuration), + (primaryChildren.treeBaseDuration = current.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4703,8 +4798,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4714,16 +4808,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4732,9 +4824,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4757,7 +4849,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4778,8 +4870,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4801,19 +4892,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4824,25 +4907,23 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } - return null; + return workInProgress.child; } var appendAllChildren, updateHostContainer, @@ -4889,16 +4970,76 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$65 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$65 = lastTailNode), + for (var lastTailNode$63 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$65 + null === lastTailNode$63 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$65.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 & 4)) { + for ( + var treeBaseDuration$65 = completedWork.selfBaseDuration, + child$66 = completedWork.child; + null !== child$66; + + ) + (newChildLanes |= child$66.lanes | child$66.childLanes), + (subtreeFlags |= child$66.subtreeFlags & 131072), + (subtreeFlags |= child$66.flags & 131072), + (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 & 131072), + (subtreeFlags |= treeBaseDuration$65.flags & 131072), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + else if (0 !== (completedWork.mode & 4)) { + 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; switch (workInProgress.tag) { @@ -4912,76 +5053,80 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); 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(); - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); ReactNativePrivateInterface.UIManager.createView( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload ); - rootContainerInstance = new ReactNativeFiberHostComponent( + renderLanes = new ReactNativeFiberHostComponent( current, - renderLanes, + type, workInProgress ); instanceCache.set(current, workInProgress); instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 128); + appendAllChildren(renderLanes, workInProgress, !1, !1); + workInProgress.stateNode = renderLanes; + finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5001,32 +5146,32 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "Text strings must be rendered within a component." ); - rootContainerInstance = allocateTag(); + renderLanes = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, + renderLanes, "RCTRawText", current, { text: newProps } ); - instanceCache.set(rootContainerInstance, workInProgress); - workInProgress.stateNode = rootContainerInstance; + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return ( (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 8) && + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress ); newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5041,89 +5186,100 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } - if (newProps || rootContainerInstance) workInProgress.flags |= 4; + if (newProps || renderLanes) workInProgress.flags |= 4; + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 4) && + newProps && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), + (renderLanes = newProps), (updatePayload = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (renderLanes = rootContainerInstance.alternate), - null === renderLanes - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = updatePayload), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null), - (rootContainerInstance.selfBaseDuration = 0), - (rootContainerInstance.treeBaseDuration = 0)) - : ((rootContainerInstance.childLanes = - renderLanes.childLanes), - (rootContainerInstance.lanes = renderLanes.lanes), - (rootContainerInstance.child = renderLanes.child), - (rootContainerInstance.memoizedProps = - renderLanes.memoizedProps), - (rootContainerInstance.memoizedState = - renderLanes.memoizedState), - (rootContainerInstance.updateQueue = - renderLanes.updateQueue), - (rootContainerInstance.type = renderLanes.type), - (updatePayload = renderLanes.dependencies), - (rootContainerInstance.dependencies = + (renderLanes.flags &= 131074), + (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 = type.subtreeFlags), + (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 }), - (rootContainerInstance.selfBaseDuration = - renderLanes.selfBaseDuration), - (rootContainerInstance.treeBaseDuration = - renderLanes.treeBaseDuration)), + (renderLanes.selfBaseDuration = type.selfBaseDuration), + (renderLanes.treeBaseDuration = type.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, @@ -5133,80 +5289,76 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + 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) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 2)) || + bubbleProperties(workInProgress), null ); } @@ -5221,9 +5373,9 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress) : null; @@ -5233,11 +5385,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5245,9 +5397,9 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress) : null @@ -5257,10 +5409,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5333,152 +5487,150 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + 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." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - 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." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$82 = finishedRoot.create; - finishedRoot.destroy = create$82(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$82 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$82; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$82 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$82, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$84 = effect.create; + effect.destroy = create$84(); } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - create$82 = finishedWork.memoizedProps.onRender; - _effect = commitTime; - "function" === typeof create$82 && - create$82( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - _effect, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - 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 hideOrUnhideAllChildren(finishedWork, isHidden) { for (var node = finishedWork; ; ) { @@ -5538,7 +5690,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { node = node.sibling; } } -function commitUnmount(finishedRoot, current) { +function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) try { injectedHook.onCommitFiberUnmount(rendererID, current); @@ -5555,26 +5707,24 @@ function commitUnmount(finishedRoot, current) { ) { var effect = (finishedRoot = finishedRoot.next); do { - var _effect2 = effect, - destroy = _effect2.destroy; - _effect2 = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (_effect2 & 4)) - enqueuePendingPassiveHookEffectUnmount(current, effect); - else { - _effect2 = current; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } + var _effect = effect, + destroy = _effect.destroy; + _effect = _effect.tag; + if (void 0 !== destroy && 0 !== (_effect & 2)) { + _effect = current; + var nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect, nearestMountedAncestor, error); } + } effect = effect.next; } while (effect !== finishedRoot); } break; case 1: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); finishedRoot = current.stateNode; if ("function" === typeof finishedRoot.componentWillUnmount) try { @@ -5582,26 +5732,34 @@ function commitUnmount(finishedRoot, current) { (finishedRoot.state = current.memoizedState), finishedRoot.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError( + current, + nearestMountedAncestor$jscomp$0, + unmountError + ); } break; case 5: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); break; case 4: - unmountHostComponents(finishedRoot, current); + unmountHostComponents( + finishedRoot, + current, + nearestMountedAncestor$jscomp$0 + ); } } -function detachFiberMutation(fiber) { +function detachFiberAfterEffects(fiber) { fiber.alternate = null; fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function isHostParent(fiber) { @@ -5636,7 +5794,7 @@ function commitPlacement(finishedWork) { "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); } - parentFiber.flags & 16 && (parentFiber.flags &= -17); + parentFiber.flags & 32 && (parentFiber.flags &= -33); a: b: for (parentFiber = finishedWork; ; ) { for (; null === parentFiber.sibling; ) { if (null === parentFiber.return || isHostParent(parentFiber.return)) { @@ -5752,7 +5910,11 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents(finishedRoot$jscomp$0, current) { +function unmountHostComponents( + finishedRoot$jscomp$0, + current, + nearestMountedAncestor$jscomp$0 +) { for ( var node = current, currentParentIsValid = !1, @@ -5790,12 +5952,13 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { a: for ( var finishedRoot = finishedRoot$jscomp$0, root = node, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0, node$jscomp$0 = root; ; ) if ( - (commitUnmount(finishedRoot, node$jscomp$0), + (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) ) (node$jscomp$0.child.return = node$jscomp$0), @@ -5822,18 +5985,18 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { [0] )) : ((finishedRoot = currentParent), - (node$jscomp$0 = node.stateNode), - recursivelyUncacheFiberNode(node$jscomp$0), + (nearestMountedAncestor = node.stateNode), + recursivelyUncacheFiberNode(nearestMountedAncestor), (root = finishedRoot._children), - (node$jscomp$0 = root.indexOf(node$jscomp$0)), - root.splice(node$jscomp$0, 1), + (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), + root.splice(nearestMountedAncestor, 1), ReactNativePrivateInterface.UIManager.manageChildren( finishedRoot._nativeTag, [], [], [], [], - [node$jscomp$0] + [nearestMountedAncestor] )); } else if (4 === node.tag) { if (null !== node.child) { @@ -5844,7 +6007,12 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { continue; } } else if ( - (commitUnmount(finishedRoot$jscomp$0, node), null !== node.child) + (commitUnmount( + finishedRoot$jscomp$0, + node, + nearestMountedAncestor$jscomp$0 + ), + null !== node.child) ) { node.child.return = node; node = node.child; @@ -5866,42 +6034,31 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do - 3 === (effect.tag & 3) && - ((finishedWork = effect.destroy), - (effect.destroy = void 0), - void 0 !== finishedWork && finishedWork()), - (effect = effect.next); - while (effect !== updateQueue); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 1: return; case 5: - updateQueue = finishedWork.stateNode; - if (null != updateQueue) { - effect = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : effect; + 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 = updateQueue.viewConfig), - instanceProps.set(updateQueue._nativeTag, effect), - (effect = diffProperties( + ((finishedWork = instance.viewConfig), + instanceProps.set(instance._nativeTag, newProps), + (newProps = diffProperties( null, current, - effect, + newProps, finishedWork.validAttributes )), - null != effect && + null != newProps && ReactNativePrivateInterface.UIManager.updateView( - updateQueue._nativeTag, + instance._nativeTag, finishedWork.uiViewClassName, - effect + newProps )); } return; @@ -5960,13 +6117,210 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + renderPriorityLevel = nextEffect; + firstChild = renderPriorityLevel.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) { + var childToDelete = firstChild[i]; + try { + unmountHostComponents(root, childToDelete, renderPriorityLevel); + var alternate = childToDelete.alternate; + childToDelete.return = null; + null !== alternate && (alternate.return = null); + } catch (error) { + captureCommitPhaseError(childToDelete, renderPriorityLevel, error); + } + } + firstChild = renderPriorityLevel.child; + if (0 !== (renderPriorityLevel.subtreeFlags & 6454) && null !== firstChild) + (firstChild.return = renderPriorityLevel), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + renderPriorityLevel = nextEffect; + try { + var flags = renderPriorityLevel.flags; + if (flags & 256) { + var current = renderPriorityLevel.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + commitPlacement(renderPriorityLevel); + renderPriorityLevel.flags &= -3; + break; + case 6: + commitPlacement(renderPriorityLevel); + renderPriorityLevel.flags &= -3; + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + break; + case 2048: + renderPriorityLevel.flags &= -2049; + break; + case 2052: + renderPriorityLevel.flags &= -2049; + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + break; + case 4: + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + } + } catch (error) { + captureCommitPhaseError( + renderPriorityLevel, + renderPriorityLevel.return, + error + ); + } + firstChild = renderPriorityLevel.sibling; + if (null !== firstChild) { + firstChild.return = renderPriorityLevel.return; + nextEffect = firstChild; + break; + } + nextEffect = renderPriorityLevel.return; + } + } +} +function commitLayoutEffects(finishedWork, root) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork, firstChild = root; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + if (0 !== (fiber$jscomp$0.flags & 324)) { + var current = fiber$jscomp$0.alternate; + try { + var finishedRoot = firstChild; + if (0 !== (fiber$jscomp$0.flags & 68)) + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, fiber$jscomp$0); + break; + case 1: + var instance = fiber$jscomp$0.stateNode; + if (fiber$jscomp$0.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + fiber$jscomp$0.elementType === fiber$jscomp$0.type + ? current.memoizedProps + : resolveDefaultProps( + fiber$jscomp$0.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = fiber$jscomp$0.updateQueue; + null !== updateQueue && + commitUpdateQueue(fiber$jscomp$0, updateQueue, instance); + break; + case 3: + var updateQueue$85 = fiber$jscomp$0.updateQueue; + if (null !== updateQueue$85) { + finishedRoot = null; + if (null !== fiber$jscomp$0.child) + switch (fiber$jscomp$0.child.tag) { + case 5: + finishedRoot = fiber$jscomp$0.child.stateNode; + break; + case 1: + finishedRoot = fiber$jscomp$0.child.stateNode; + } + commitUpdateQueue( + fiber$jscomp$0, + updateQueue$85, + finishedRoot + ); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = fiber$jscomp$0.memoizedProps.onRender, + commitTime$88 = commitTime; + current = null === current ? "mount" : "update"; + "function" === typeof onRender && + onRender( + fiber$jscomp$0.memoizedProps.id, + current, + fiber$jscomp$0.actualDuration, + fiber$jscomp$0.treeBaseDuration, + fiber$jscomp$0.actualStartTime, + commitTime$88, + finishedRoot.memoizedInteractions + ); + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + 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." + ); + } + if (fiber$jscomp$0.flags & 256) { + finishedRoot = void 0; + var ref = fiber$jscomp$0.ref; + if (null !== ref) { + var instance$jscomp$0 = fiber$jscomp$0.stateNode; + switch (fiber$jscomp$0.tag) { + case 5: + finishedRoot = instance$jscomp$0; + break; + default: + finishedRoot = instance$jscomp$0; + } + "function" === typeof ref + ? ref(finishedRoot) + : (ref.current = finishedRoot); + } + } + } catch (error) { + captureCommitPhaseError( + fiber$jscomp$0, + fiber$jscomp$0.return, + error + ); + } + } + if (fiber$jscomp$0 === fiber) { + nextEffect = null; + break; + } + finishedRoot = fiber$jscomp$0.sibling; + if (null !== finishedRoot) { + finishedRoot.return = fiber$jscomp$0.return; + nextEffect = finishedRoot; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, @@ -5979,14 +6333,11 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -5994,17 +6345,12 @@ var ceil = Math.ceil, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, pendingPassiveEffectsLanes = 0, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, spawnedWorkDuringRender = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -6014,30 +6360,22 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } + if (0 === (fiber & 1)) return 1; + if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) + ? (fiber = findUpdateLane(12)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); + (fiber = findUpdateLane(fiber))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -6070,7 +6408,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime), schedulePendingInteractions(fiber, lane)); - mostRecentlyUpdatedRoot = fiber; + return fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6095,15 +6433,15 @@ function ensureRootIsScheduled(root, currentTime) { 0 < lanes; ) { - var index$7 = 31 - clz32(lanes), - lane = 1 << index$7, - expirationTime = expirationTimes[index$7]; + var index$6 = 31 - clz32(lanes), + lane = 1 << index$6, + expirationTime = expirationTimes[index$6]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { expirationTime = currentTime; getHighestPriorityLanes(lane); var priority = return_highestLanePriority; - expirationTimes[index$7] = + expirationTimes[index$6] = 10 <= priority ? expirationTime + 250 : 6 <= priority @@ -6118,45 +6456,42 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && + 0 === suspendedLanes + ? (null !== existingCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); - } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); - root.callbackPriority = currentTime; - root.callbackNode = existingCallbackNode; - } -} -function performConcurrentWorkOnRoot(root) { + (root.callbackPriority = 0)) + : root.callbackPriority !== currentTime && + (null != existingCallbackNode && + Scheduler_cancelCallback(existingCallbackNode), + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = null)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority( + currentTime + )), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))), + (root.callbackPriority = currentTime), + (root.callbackNode = existingCallbackNode)); +} +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; + currentEventTransitionLane = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -6167,8 +6502,14 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; + if (didTimeout) + return ( + (root.expiredLanes |= lanes & root.pendingLanes), + ensureRootIsScheduled(root, now()), + null + ); var lanes$jscomp$0 = lanes; - var exitStatus = executionContext; + didTimeout = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( @@ -6190,21 +6531,19 @@ function performConcurrentWorkOnRoot(root) { resetContextDependencies(); tracing.__interactionsRef.current = lanes$jscomp$0; ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = exitStatus; + executionContext = didTimeout; null !== workInProgress - ? (exitStatus = 0) + ? (didTimeout = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && + (didTimeout = workInProgressRootExitStatus)); + if (0 !== didTimeout) { + 2 === didTimeout && ((executionContext |= 64), root.hydrate && (root.hydrate = !1), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6212,7 +6551,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6222,9 +6561,9 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 125829120) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; prevDispatcher = root.suspendedLanes; @@ -6235,7 +6574,7 @@ function performConcurrentWorkOnRoot(root) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -6243,13 +6582,13 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; + if ((lanes & 8388096) === lanes) break; + didTimeout = root.eventTimes; for (prevDispatcher = -1; 0 < lanes; ) { - var index$6 = 31 - clz32(lanes); - lanes$jscomp$0 = 1 << index$6; - index$6 = exitStatus[index$6]; - index$6 > prevDispatcher && (prevDispatcher = index$6); + var index$5 = 31 - clz32(lanes); + lanes$jscomp$0 = 1 << index$5; + index$5 = didTimeout[index$5]; + index$5 > prevDispatcher && (prevDispatcher = index$5); lanes &= ~lanes$jscomp$0; } lanes = prevDispatcher; @@ -6295,9 +6634,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$11 = 31 - clz32(suspendedLanes), - lane = 1 << index$11; - root[index$11] = -1; + var index$7 = 31 - clz32(suspendedLanes), + lane = 1 << index$7; + root[index$7] = -1; suspendedLanes &= ~lane; } } @@ -6305,17 +6644,12 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( + var lanes = root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); + ? workInProgressRootRenderLanes + : getNextLanes(root, 0); + var exitStatus = renderRootSync(root, lanes); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6334,11 +6668,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6378,7 +6707,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6388,10 +6717,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } spawnedWorkDuringRender = null; } function handleError(root$jscomp$0, thrownValue) { @@ -6422,7 +6770,7 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress = null; break; } - erroredWork.mode & 8 && + erroredWork.mode & 4 && stopProfilerTimerIfRunningAndRecordDelta(erroredWork, !0); a: { var root = root$jscomp$0, @@ -6430,15 +6778,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6449,15 +6800,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$77 = returnFiber; + workInProgress$79 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { - var nextState = workInProgress$77.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$79.tag)) { + var nextState = workInProgress$79.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$77.memoizedProps; + var props = workInProgress$79.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6469,16 +6820,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$77.updateQueue; + var wakeables = workInProgress$79.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$77.updateQueue = updateQueue; + workInProgress$79.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$77.mode & 2)) { - workInProgress$77.flags |= 64; - sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + if ( + 0 === (workInProgress$79.mode & 1) && + workInProgress$79 !== returnFiber + ) { + workInProgress$79.flags |= 128; + sourceFiber.flags |= 65536; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6509,12 +6863,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$77.flags |= 8192; - workInProgress$77.lanes = thrownValue; + workInProgress$79.flags |= 16384; + workInProgress$79.lanes = thrownValue; break a; } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$79 = workInProgress$79.return; + } while (null !== workInProgress$79); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6523,47 +6877,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$77 = returnFiber; + workInProgress$79 = returnFiber; do { - switch (workInProgress$77.tag) { + switch (workInProgress$79.tag) { case 3: root = value; - workInProgress$77.flags |= 8192; + workInProgress$79.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$78 = createRootErrorUpdate( - workInProgress$77, + workInProgress$79.lanes |= thrownValue; + var update$80 = createRootErrorUpdate( + workInProgress$79, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$78); + enqueueCapturedUpdate(workInProgress$79, update$80); break a; case 1: root = value; - var ctor = workInProgress$77.type, - instance = workInProgress$77.stateNode; + var ctor = workInProgress$79.type, + instance = workInProgress$79.stateNode; if ( - 0 === (workInProgress$77.flags & 64) && + 0 === (workInProgress$79.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$77.flags |= 8192; + workInProgress$79.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$81 = createClassErrorUpdate( - workInProgress$77, + workInProgress$79.lanes |= thrownValue; + var update$83 = createClassErrorUpdate( + workInProgress$79, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$81); + enqueueCapturedUpdate(workInProgress$79, update$83); break a; } } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$79 = workInProgress$79.return; + } while (null !== workInProgress$79); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6622,7 +6976,7 @@ function workLoopConcurrent() { } function performUnitOfWork(unitOfWork) { var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 8) + 0 !== (unitOfWork.mode & 4) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current = beginWork$1(current, unitOfWork, subtreeRenderLanes)), @@ -6639,8 +6993,8 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - if (0 === (completedWork.mode & 8)) + if (0 === (completedWork.flags & 8192)) { + if (0 === (completedWork.mode & 4)) current = completeWork(current, completedWork, subtreeRenderLanes); else { var fiber = completedWork; @@ -6653,65 +7007,14 @@ function completeUnitOfWork(unitOfWork) { workInProgress = current; return; } - current = completedWork; - if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) - ) { - fiber = 0; - if (0 !== (current.mode & 8)) { - for ( - var actualDuration = current.actualDuration, - treeBaseDuration = current.selfBaseDuration, - shouldBubbleActualDurations = - null === current.alternate || - current.child !== current.alternate.child, - child = current.child; - null !== child; - - ) - (fiber |= child.lanes | child.childLanes), - shouldBubbleActualDurations && - (actualDuration += child.actualDuration), - (treeBaseDuration += child.treeBaseDuration), - (child = child.sibling); - 13 === current.tag && - null !== current.memoizedState && - ((shouldBubbleActualDurations = current.child), - null !== shouldBubbleActualDurations && - (treeBaseDuration -= - shouldBubbleActualDurations.treeBaseDuration)); - current.actualDuration = actualDuration; - current.treeBaseDuration = treeBaseDuration; - } else - for (actualDuration = current.child; null !== actualDuration; ) - (fiber |= actualDuration.lanes | actualDuration.childLanes), - (actualDuration = actualDuration.sibling); - current.childLanes = fiber; - } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } - if (0 !== (completedWork.mode & 8)) { + if (0 !== (completedWork.mode & 4)) { stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1); current = completedWork.actualDuration; for (fiber = completedWork.child; null !== fiber; ) @@ -6719,8 +7022,9 @@ function completeUnitOfWork(unitOfWork) { completedWork.actualDuration = current; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6751,190 +7055,65 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$12 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$12; - remainingLanes$jscomp$0[index$12] = 0; - eventTimes[index$12] = -1; - expirationTimes[index$12] = -1; - noLongerPendingLanes &= ~lane; - } + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && + 0 === (remainingLanes & 8) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { + remainingLanes = executionContext; executionContext |= 32; - eventTimes = pushInteractions(root); - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; + var prevInteractions = pushInteractions(root); + ReactCurrentOwner$2.current = null; + commitBeforeMutationEffects(root, finishedWork); commitTime = now$1(); - nextEffect = remainingLanes; - do - try { - for (expirationTimes = root; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - break; - case 6: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - noLongerPendingLanes = nextEffect; - unmountHostComponents(expirationTimes, noLongerPendingLanes); - var alternate = noLongerPendingLanes.alternate; - detachFiberMutation(noLongerPendingLanes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$91) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$91); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); + commitMutationEffects(root, renderPriorityLevel, finishedWork); root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance; - break; - default: - current = instance; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$92) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$92); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; + commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - tracing.__interactionsRef.current = eventTimes; - executionContext = remainingLanes$jscomp$0; + tracing.__interactionsRef.current = prevInteractions; + executionContext = remainingLanes; } else (root.current = finishedWork), (commitTime = now$1()); - if ((flags$jscomp$0 = rootDoesHavePassiveEffects)) + if ((prevInteractions = rootDoesHavePassiveEffects)) (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes), (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (ref = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((instance = nextEffect), - (instance.sibling = null), - (instance.stateNode = null)), - (nextEffect = ref); remainingLanes = root.pendingLanes; if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) - for ( - ref = spawnedWorkDuringRender, - spawnedWorkDuringRender = null, - instance = 0; - instance < ref.length; - instance++ - ) - scheduleInteractions(root, ref[instance], root.memoizedInteractions); + if (null !== spawnedWorkDuringRender) { + var expirationTimes = spawnedWorkDuringRender; + spawnedWorkDuringRender = null; + for (var i = 0; i < expirationTimes.length; i++) + scheduleInteractions( + root, + expirationTimes[i], + root.memoizedInteractions + ); + } schedulePendingInteractions(root, remainingLanes); } else legacyErrorBoundariesThatAlreadyFailed = null; - flags$jscomp$0 || finishPendingInteractions(root, lanes); - 1 === remainingLanes + prevInteractions || finishPendingInteractions(root, lanes); + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - renderPriorityLevel, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6945,30 +7124,6 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6980,24 +7135,6 @@ function flushPassiveEffects() { } return !1; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects, @@ -7008,41 +7145,104 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var prevInteractions = pushInteractions(root), - unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$97 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$97.destroy; - effect$97.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); + var prevInteractions = pushInteractions(root); + for (nextEffect = root.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + if (fiber$jscomp$0 === fiberToDelete) { + nextEffect = null; + break; + } + child$jscomp$0 = fiber$jscomp$0.sibling; + if (null !== child$jscomp$0) { + child$jscomp$0.return = fiber$jscomp$0.return; + nextEffect = child$jscomp$0; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } + fiber$jscomp$0 = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); + null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); + } + nextEffect = fiber; } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$97 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; - try { - var create$101 = effect$97.create; - effect$97.destroy = create$101(); - } catch (error$102) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$102); } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + a: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + child = fiber.sibling; + if (null !== child) { + child.return = fiber.return; + nextEffect = child; + break a; + } + nextEffect = fiber.return; + } } - for (unmountEffects = root.current.firstEffect; null !== unmountEffects; ) - (create$101 = unmountEffects.nextEffect), - (unmountEffects.nextEffect = null), - unmountEffects.flags & 8 && - ((unmountEffects.sibling = null), (unmountEffects.stateNode = null)), - (unmountEffects = create$101); + for (nextEffect = fiber = root.current; null !== nextEffect; ) + if ( + ((child = nextEffect), + (deletions = child.child), + 0 !== (child.subtreeFlags & 1040) && null !== deletions) + ) + (deletions.return = child), (nextEffect = deletions); + else + a: for (child = fiber; null !== nextEffect; ) { + deletions = nextEffect; + if (0 !== (deletions.flags & 1024)) + try { + switch (deletions.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, deletions); + } + } catch (error) { + captureCommitPhaseError(deletions, deletions.return, error); + } + if (deletions === child) { + nextEffect = null; + break a; + } + i = deletions.sibling; + if (null !== i) { + i.return = deletions.return; + nextEffect = i; + break a; + } + nextEffect = deletions.return; + } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, lanes); executionContext = prevExecutionContext; @@ -7060,43 +7260,51 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { ensureRootIsScheduled(rootFiber, sourceFiber), schedulePendingInteractions(rootFiber, 1)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update), - schedulePendingInteractions(fiber, 1); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber), + schedulePendingInteractions(nearestMountedAncestor, 1)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -7108,7 +7316,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 125829120) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -7122,14 +7330,13 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + 0 === (wakeable & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) + : 0 === (wakeable & 2) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -7146,85 +7353,90 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateLanes; - break; - case 12: - 0 !== (renderLanes & workInProgress.childLanes) && - (workInProgress.flags |= 4); - updateLanes = workInProgress.stateNode; - updateLanes.effectDuration = 0; - updateLanes.passiveEffectDuration = 0; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, + if (0 === (renderLanes & updateLanes)) { + didReceiveUpdate = !1; + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer( workInProgress, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + break; + case 10: + updateLanes = workInProgress.type._context; + var nextValue = workInProgress.memoizedProps.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = nextValue; + break; + case 12: + 0 !== (renderLanes & workInProgress.childLanes) && + (workInProgress.flags |= 4); + updateLanes = workInProgress.stateNode; + updateLanes.effectDuration = 0; + updateLanes.passiveEffectDuration = 0; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); + return null !== workInProgress ? workInProgress.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; + case 19: + updateLanes = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; + } + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); + } + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7236,22 +7448,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7261,8 +7473,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7273,9 +7485,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7287,28 +7499,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7317,7 +7529,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7326,7 +7538,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7335,8 +7547,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7344,7 +7556,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7352,32 +7564,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7388,19 +7600,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7440,16 +7651,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7490,27 +7701,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; + nextValue = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue); - context$jscomp$0._currentValue = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = nextValue.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = hasContext; + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = objectIs(oldValue, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits(oldValue, hasContext) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7522,15 +7727,14 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + oldValue = workInProgress.child, + null !== oldValue && (oldValue.return = workInProgress); + null !== oldValue; ) { - var list = context$jscomp$0.dependencies; + var list = oldValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + getDerivedStateFromProps = oldValue.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7540,20 +7744,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (1 === oldValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + oldValue.lanes |= renderLanes; + dependency = oldValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(oldValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7561,16 +7769,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + 10 === oldValue.tag + ? oldValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; + : oldValue.child + : oldValue.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + getDerivedStateFromProps.return = oldValue; else for ( - getDerivedStateFromProps = context$jscomp$0; + getDerivedStateFromProps = oldValue; null !== getDerivedStateFromProps; ) { @@ -7578,20 +7786,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + oldValue = getDerivedStateFromProps.sibling; + if (null !== oldValue) { + oldValue.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = oldValue; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - context$jscomp$0 = getDerivedStateFromProps; + oldValue = getDerivedStateFromProps; } + } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7599,28 +7808,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7638,11 +7847,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7652,8 +7861,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7754,9 +7963,9 @@ function finishPendingInteractions(root, committedLanes) { if (null !== subscriber && 0 === interaction.__count) try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$103) { + } catch (error$96) { scheduleCallback(99, function() { - throw error$103; + throw error$96; }); } })); @@ -7772,8 +7981,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; this.actualDuration = 0; @@ -7814,11 +8023,11 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null), + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); + workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7855,15 +8064,18 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 8; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + 1 <= + (null == pendingProps.unstable_level + ? 1 + : pendingProps.unstable_level) && (mode |= 16); break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 4)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -8054,7 +8266,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -8093,10 +8306,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_930 = { + devToolsConfig$jscomp$inline_986 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8111,11 +8324,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1148 = { - bundleType: devToolsConfig$jscomp$inline_930.bundleType, - version: devToolsConfig$jscomp$inline_930.version, - rendererPackageName: devToolsConfig$jscomp$inline_930.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_930.rendererConfig, +var internals$jscomp$inline_1282 = { + bundleType: devToolsConfig$jscomp$inline_986.bundleType, + version: devToolsConfig$jscomp$inline_986.version, + rendererPackageName: devToolsConfig$jscomp$inline_986.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_986.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8130,7 +8343,7 @@ var internals$jscomp$inline_1148 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_930.findFiberByHostInstance || + devToolsConfig$jscomp$inline_986.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -8139,16 +8352,16 @@ var internals$jscomp$inline_1148 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1149 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1283 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1149.isDisabled && - hook$jscomp$inline_1149.supportsFiber + !hook$jscomp$inline_1283.isDisabled && + hook$jscomp$inline_1283.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1149.inject( - internals$jscomp$inline_1148 + (rendererID = hook$jscomp$inline_1283.inject( + internals$jscomp$inline_1282 )), - (injectedHook = hook$jscomp$inline_1149); + (injectedHook = hook$jscomp$inline_1283); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -8198,7 +8411,7 @@ exports.render = function(element, containerTag, callback) { if (!root) { root = new FiberRootNode(containerTag, 0, !1); var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 8); + isDevToolsPresent && (JSCompiler_inline_result |= 4); JSCompiler_inline_result = createFiber( 3, null, @@ -8207,6 +8420,7 @@ exports.render = function(element, containerTag, callback) { ); root.current = JSCompiler_inline_result; JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index 31edc17fd5ee2e..536ce9a6f30b65 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -8,6 +8,8 @@ * @flow */ +'use strict'; + import {BatchedBridge} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; // TODO @sema: Adjust types diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index 552b118556aaf0..462abeac94beee 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -8,12 +8,7 @@ * @flow strict */ -import type { - ElementRef, - ElementType, - MixedElement, - AbstractComponent, -} from 'react'; +import type {ElementRef, ElementType, Element, AbstractComponent} from 'react'; export type MeasureOnSuccessCallback = ( x: number, @@ -49,7 +44,7 @@ type AttributeType = // or we allow them to define specific types and use this hack type AnyAttributeType = AttributeType<$FlowFixMe, $FlowFixMe>; -type AttributeConfiguration = $ReadOnly<{ +export type AttributeConfiguration = $ReadOnly<{ [propName: string]: AnyAttributeType, style: $ReadOnly<{ [propName: string]: AnyAttributeType, @@ -185,7 +180,7 @@ export type ReactNativeType = { eventType: string, ): void, render( - element: MixedElement, + element: Element, containerTag: number, callback: ?() => void, ): ?ElementRef, @@ -213,7 +208,7 @@ export type ReactFabricType = { eventType: string, ): void, render( - element: MixedElement, + element: Element, containerTag: number, callback: ?() => void, ): ?ElementRef, diff --git a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js index 0b3b8cc3d01194..5f219fea65208c 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -8,6 +8,10 @@ * @flow strict-local */ +/* eslint-disable react-internal/invariant-args */ + +'use strict'; + import {type ViewConfig} from './ReactNativeTypes'; import invariant from 'invariant'; diff --git a/Libraries/Renderer/shims/createReactNativeComponentClass.js b/Libraries/Renderer/shims/createReactNativeComponentClass.js index 0f893dfd24a0b9..f8f4c9284e4c32 100644 --- a/Libraries/Renderer/shims/createReactNativeComponentClass.js +++ b/Libraries/Renderer/shims/createReactNativeComponentClass.js @@ -8,6 +8,8 @@ * @flow strict-local */ +'use strict'; + import {ReactNativeViewConfigRegistry} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import {type ViewConfig} from './ReactNativeTypes';