diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index ca2ac7272eb294..347ba9d44caa00 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -87d375afd0d9394646a4bcddcebb7b15ffaa7e9e \ No newline at end of file +55bc393f726ddf3def83ca5a43cfc38a45d2e421 \ 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 6a3270f6ff0f29..220395e35f439f 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -18,16 +18,15 @@ if (__DEV__) { require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); var React = require("react"); -var checkPropTypes = require("prop-types/checkPropTypes"); var Scheduler = require("scheduler"); +var checkPropTypes = require("prop-types/checkPropTypes"); var tracing = require("scheduler/tracing"); -// Do not require this module directly! Use a normal error constructor with +// Do not require this module directly! Use normal `invariant` calls with // template literal strings. The messages will be converted to ReactError during // build, and in production they will be minified. -function ReactError(message) { - var error = new Error(message); +function ReactError(error) { error.name = "Invariant Violation"; return error; } @@ -69,9 +68,11 @@ function recomputePluginOrdering() { (function() { if (!(pluginIndex > -1)) { throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); } })(); @@ -81,9 +82,11 @@ function recomputePluginOrdering() { (function() { if (!pluginModule.extractEvents) { throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); } })(); @@ -99,11 +102,13 @@ function recomputePluginOrdering() { ) ) { throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } })(); @@ -123,9 +128,11 @@ function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { (function() { if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ) ); } })(); @@ -166,9 +173,11 @@ function publishRegistrationName(registrationName, pluginModule, eventName) { (function() { if (!!registrationNameModules[registrationName]) { throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); } })(); @@ -229,7 +238,9 @@ function injectEventPluginOrder(injectedEventPluginOrder) { (function() { if (!!eventPluginOrder) { throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); } })(); @@ -262,9 +273,11 @@ function injectEventPluginsByName(injectedNamesToPlugins) { (function() { if (!!namesToPlugins[pluginName]) { throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); } })(); @@ -344,7 +357,9 @@ var invokeGuardedCallbackImpl = function( (function() { if (!(typeof document !== "undefined")) { throw ReactError( - "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." + Error( + "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." + ) ); } })(); @@ -573,7 +588,9 @@ function clearCaughtError() { (function() { { throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -787,7 +804,7 @@ function executeDirectDispatch(event) { var dispatchInstance = event._dispatchInstances; (function() { if (!!Array.isArray(dispatchListener)) { - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); } })(); event.currentTarget = dispatchListener @@ -825,7 +842,9 @@ function accumulateInto(current, next) { (function() { if (!(next != null)) { throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); } })(); @@ -913,7 +932,9 @@ function runEventsInBatch(events) { (function() { if (!!eventQueue) { throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); } })(); @@ -1014,11 +1035,13 @@ function getListener(inst, registrationName) { (function() { if (!(!listener || typeof listener === "function")) { throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); } })(); @@ -1091,8 +1114,8 @@ var SimpleMemoComponent = 15; var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedSuspenseComponent = 18; -var EventComponent = 19; -var EventTarget = 20; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; function getParent(inst) { do { @@ -1614,7 +1637,9 @@ function releasePooledEvent(event) { (function() { if (!(event instanceof EventConstructor)) { throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); } })(); @@ -1726,7 +1751,7 @@ function getTouchIdentifier(_ref) { (function() { if (!(identifier != null)) { - throw ReactError("Touch object is missing identifier."); + throw ReactError(Error("Touch object is missing identifier.")); } })(); { @@ -1766,7 +1791,7 @@ function recordTouchMove(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.error( + console.warn( "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -1787,7 +1812,7 @@ function recordTouchEnd(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.error( + console.warn( "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -1859,7 +1884,9 @@ function accumulate(current, next) { (function() { if (!(next != null)) { throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error( + "accumulate(...): Accumulated items must not be null or undefined." + ) ); } })(); @@ -2483,7 +2510,9 @@ var ReactNativeBridgeEventPlugin = { (function() { if (!(bubbleDispatchConfig || directDispatchConfig)) { throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); } })(); @@ -2538,7 +2567,7 @@ function getTagFromInstance(inst) { var tag = inst.stateNode.canonical._nativeTag; (function() { if (!tag) { - throw ReactError("All native instances should have a tag."); + throw ReactError(Error("All native instances should have a tag.")); } })(); return tag; @@ -2608,6 +2637,11 @@ if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { current: null }; } +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. @@ -2622,6 +2656,8 @@ var REACT_STRICT_MODE_TYPE = hasSymbol var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; +// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") @@ -2630,19 +2666,15 @@ var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 0xead0; var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -var REACT_EVENT_COMPONENT_TYPE = hasSymbol - ? Symbol.for("react.event_component") +var REACT_FUNDAMENTAL_TYPE = hasSymbol + ? Symbol.for("react.fundamental") : 0xead5; -var REACT_EVENT_TARGET_TYPE = hasSymbol - ? Symbol.for("react.event_target") - : 0xead6; - -// React event targets -var REACT_EVENT_TARGET_TOUCH_HIT = hasSymbol - ? Symbol.for("react.event_target.touch_hit") - : 0xead7; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; @@ -2668,27 +2700,6 @@ function refineResolvedLazyComponent(lazyComponent) { return lazyComponent._status === Resolved ? lazyComponent._result : null; } -// Re-export dynamic flags from the fbsource version. -var _require = require("../shims/ReactFeatureFlags"); - -var debugRenderPhaseSideEffects = _require.debugRenderPhaseSideEffects; - -var enableUserTimingAPI = true; -var enableProfilerTimer = true; -var enableSchedulerTracing = true; -var enableSuspenseServerRenderer = false; - -var debugRenderPhaseSideEffectsForStrictMode = true; - -var disableYielding = false; - -var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; -var warnAboutDeprecatedLifecycles = true; -var warnAboutDeprecatedSetNativeProps = true; -var enableEventAPI = false; - -// Only used in www builds. - function getWrappedName(outerType, innerType, wrapperName) { var functionName = innerType.displayName || innerType.name || ""; return ( @@ -2718,8 +2729,6 @@ function getComponentName(type) { return type; } switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -2730,6 +2739,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if (typeof type === "object") { switch (type.$$typeof) { @@ -2749,28 +2760,6 @@ function getComponentName(type) { } break; } - case REACT_EVENT_COMPONENT_TYPE: { - if (enableEventAPI) { - var eventComponent = type; - var displayName = eventComponent.displayName; - if (displayName !== undefined) { - return displayName; - } - } - break; - } - case REACT_EVENT_TARGET_TYPE: { - if (enableEventAPI) { - var eventTarget = type; - if (eventTarget.type === REACT_EVENT_TARGET_TOUCH_HIT) { - return "TouchHitTarget"; - } - var _displayName = eventTarget.displayName; - if (_displayName !== undefined) { - return _displayName; - } - } - } } } return null; @@ -2871,7 +2860,7 @@ function isMounted(component) { function assertIsMounted(fiber) { (function() { if (!(isFiberMountedImpl(fiber) === MOUNTED)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } })(); } @@ -2883,7 +2872,9 @@ function findCurrentFiberUsingSlowPath(fiber) { var state = isFiberMountedImpl(fiber); (function() { if (!(state !== UNMOUNTED)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); if (state === MOUNTING) { @@ -2939,7 +2930,9 @@ function findCurrentFiberUsingSlowPath(fiber) { // way this could possibly happen is if this was unmounted, if at all. (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } @@ -2995,7 +2988,9 @@ function findCurrentFiberUsingSlowPath(fiber) { (function() { if (!didFindChild) { throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } })(); @@ -3005,7 +3000,9 @@ function findCurrentFiberUsingSlowPath(fiber) { (function() { if (!(a.alternate === b)) { throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -3014,7 +3011,7 @@ function findCurrentFiberUsingSlowPath(fiber) { // unmounted. (function() { if (!(a.tag === HostRoot)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } })(); if (a.stateNode.current === a) { @@ -3580,7 +3577,9 @@ function restoreStateOfTarget(target) { (function() { if (!(typeof restoreImpl === "function")) { throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -3609,6 +3608,31 @@ function restoreStateIfNeeded() { } } +// Re-export dynamic flags from the fbsource version. +var _require = require("../shims/ReactFeatureFlags"); + +var debugRenderPhaseSideEffects = _require.debugRenderPhaseSideEffects; + +var enableUserTimingAPI = true; +var enableProfilerTimer = true; +var enableSchedulerTracing = true; +var enableSuspenseServerRenderer = false; + +var debugRenderPhaseSideEffectsForStrictMode = true; + +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; +var warnAboutDeprecatedLifecycles = true; +var warnAboutDeprecatedSetNativeProps = true; +var enableFlareAPI = false; +var enableFundamentalAPI = false; + +var revertPassiveEffectsChange = false; +var enableUserBlockingEvents = false; +var enableSuspenseCallback = false; +var warnAboutDefaultPropsOnFunctionComponents = false; + +// Only used in www builds. + // Used as a way to call batchedUpdates when we don't have a reference to // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when @@ -3616,630 +3640,1484 @@ function restoreStateIfNeeded() { // scheduled work and instead do synchronous work. // Defaults -var _batchedUpdatesImpl = function(fn, bookkeeping) { +var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; -var _flushInteractiveUpdatesImpl = function() {}; +var discreteUpdatesImpl = function(fn, a, b, c) { + return fn(a, b, c); +}; +var flushDiscreteUpdatesImpl = function() {}; +var batchedEventUpdatesImpl = batchedUpdatesImpl; + +var isInsideEventHandler = false; + +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} -var isBatching = false; function batchedUpdates(fn, bookkeeping) { - if (isBatching) { + if (isInsideEventHandler) { // If we are currently inside another batch, we need to wait until it // fully completes before restoring state. return fn(bookkeeping); } - isBatching = true; + isInsideEventHandler = true; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - // Here we wait until all updates have propagated, which is important - // when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - // Then we restore state of any controlled component. - isBatching = false; - var controlledComponentsHavePendingUpdates = needsStateRestore(); - if (controlledComponentsHavePendingUpdates) { - // If a controlled event was fired, we may need to restore the state of - // the DOM node back to the controlled value. This is necessary when React - // bails out of the update without touching the DOM. - _flushInteractiveUpdatesImpl(); - restoreStateIfNeeded(); - } + isInsideEventHandler = false; + finishEventHandler(); + } +} + +function batchedEventUpdates(fn, a, b) { + if (isInsideEventHandler) { + // If we are currently inside another batch, we need to wait until it + // fully completes before restoring state. + return fn(a, b); + } + isInsideEventHandler = true; + try { + return batchedEventUpdatesImpl(fn, a, b); + } finally { + isInsideEventHandler = false; + finishEventHandler(); + } +} + +function discreteUpdates(fn, a, b, c) { + var prevIsInsideEventHandler = isInsideEventHandler; + isInsideEventHandler = true; + try { + return discreteUpdatesImpl(fn, a, b, c); + } finally { + isInsideEventHandler = prevIsInsideEventHandler; + if (!isInsideEventHandler) { + finishEventHandler(); + } + } +} + +var lastFlushedEventTimeStamp = 0; +function flushDiscreteUpdatesIfNeeded(timeStamp) { + // event.timeStamp isn't overly reliable due to inconsistencies in + // how different browsers have historically provided the time stamp. + // Some browsers provide high-resolution time stamps for all events, + // some provide low-resolution time stamps for all events. FF < 52 + // even mixes both time stamps together. Some browsers even report + // negative time stamps or time stamps that are 0 (iOS9) in some cases. + // Given we are only comparing two time stamps with equality (!==), + // we are safe from the resolution differences. If the time stamp is 0 + // we bail-out of preventing the flush, which can affect semantics, + // such as if an earlier flush removes or adds event listeners that + // are fired in the subsequent flush. However, this is the same + // behaviour as we had before this change, so the risks are low. + if ( + !isInsideEventHandler && + (!enableFlareAPI || + timeStamp === 0 || + lastFlushedEventTimeStamp !== timeStamp) + ) { + lastFlushedEventTimeStamp = timeStamp; + flushDiscreteUpdatesImpl(); } } function setBatchingImplementation( - batchedUpdatesImpl, - interactiveUpdatesImpl, - flushInteractiveUpdatesImpl + _batchedUpdatesImpl, + _discreteUpdatesImpl, + _flushDiscreteUpdatesImpl, + _batchedEventUpdatesImpl ) { - _batchedUpdatesImpl = batchedUpdatesImpl; - _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; + batchedUpdatesImpl = _batchedUpdatesImpl; + discreteUpdatesImpl = _discreteUpdatesImpl; + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; + batchedEventUpdatesImpl = _batchedEventUpdatesImpl; } -function dispatchEvent(target, topLevelType, nativeEvent) { - var targetFiber = target; - batchedUpdates(function() { - runExtractedPluginEventsInBatch( - topLevelType, - targetFiber, - nativeEvent, - nativeEvent.target - ); - }); - // React Native doesn't use ReactControlledComponent but if it did, here's - // where it would do it. +function _classCallCheck$1(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } } -// Renderers that don't support mutation -// can re-export everything from this module. +function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError( + "this hasn't been initialised - super() hasn't been called" + ); + } + return call && (typeof call === "object" || typeof call === "function") + ? call + : self; +} -function shim() { - (function() { - { - throw ReactError( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); +function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError( + "Super expression must either be null or a function, not " + + typeof superClass + ); + } + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true } - })(); + }); + if (superClass) + Object.setPrototypeOf + ? Object.setPrototypeOf(subClass, superClass) + : (subClass.__proto__ = superClass); } -// Mutation (when unsupported) -var supportsMutation = false; -var appendChild = shim; -var appendChildToContainer = shim; -var commitTextUpdate = shim; -var commitMount = shim; -var commitUpdate = shim; -var insertBefore = shim; -var insertInContainerBefore = shim; -var removeChild = shim; -var removeChildFromContainer = shim; -var resetTextContent = shim; -var hideInstance = shim; -var hideTextInstance = shim; -var unhideInstance = shim; -var unhideTextInstance = shim; +/** + * Class only exists for its Flow type. + */ +var ReactNativeComponent = (function(_React$Component) { + _inherits(ReactNativeComponent, _React$Component); -// Renderers that don't support hydration -// can re-export everything from this module. + function ReactNativeComponent() { + _classCallCheck$1(this, ReactNativeComponent); -function shim$1() { - (function() { - { - throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); -} + return _possibleConstructorReturn( + this, + _React$Component.apply(this, arguments) + ); + } -// Hydration (when unsupported) + ReactNativeComponent.prototype.blur = function blur() {}; -var supportsHydration = false; -var canHydrateInstance = shim$1; -var canHydrateTextInstance = shim$1; -var canHydrateSuspenseInstance = shim$1; -var isSuspenseInstancePending = shim$1; -var isSuspenseInstanceFallback = shim$1; -var registerSuspenseInstanceRetry = shim$1; -var getNextHydratableSibling = shim$1; -var getFirstHydratableChild = shim$1; -var hydrateInstance = shim$1; -var hydrateTextInstance = shim$1; -var getNextHydratableInstanceAfterSuspenseInstance = shim$1; -var clearSuspenseBoundary = shim$1; -var clearSuspenseBoundaryFromContainer = shim$1; -var didNotMatchHydratedContainerTextInstance = shim$1; -var didNotMatchHydratedTextInstance = shim$1; -var didNotHydrateContainerInstance = shim$1; -var didNotHydrateInstance = shim$1; -var didNotFindHydratableContainerInstance = shim$1; -var didNotFindHydratableContainerTextInstance = shim$1; -var didNotFindHydratableContainerSuspenseInstance = shim$1; -var didNotFindHydratableInstance = shim$1; -var didNotFindHydratableTextInstance = shim$1; -var didNotFindHydratableSuspenseInstance = shim$1; + ReactNativeComponent.prototype.focus = function focus() {}; -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} + ReactNativeComponent.prototype.measure = function measure(callback) {}; -// Modules provided by RN: -var _nativeFabricUIManage = nativeFabricUIManager; -var createNode = _nativeFabricUIManage.createNode; -var cloneNode = _nativeFabricUIManage.cloneNode; -var cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren; -var cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps; -var cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps; -var createChildNodeSet = _nativeFabricUIManage.createChildSet; -var appendChildNode = _nativeFabricUIManage.appendChild; -var appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet; -var completeRoot = _nativeFabricUIManage.completeRoot; -var registerEventHandler = _nativeFabricUIManage.registerEventHandler; -var fabricMeasure = _nativeFabricUIManage.measure; -var fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow; -var fabricMeasureLayout = _nativeFabricUIManage.measureLayout; -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; + ReactNativeComponent.prototype.measureInWindow = function measureInWindow( + callback + ) {}; -// 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. + ReactNativeComponent.prototype.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) {}; -var nextReactTag = 2; + ReactNativeComponent.prototype.setNativeProps = function setNativeProps( + nativeProps + ) {}; -// TODO: Remove this conditional once all changes have propagated. -if (registerEventHandler) { - /** - * Register the event emitter with the native bridge - */ - registerEventHandler(dispatchEvent); -} + return ReactNativeComponent; +})(React.Component); /** - * This is used for refs on host components. + * This type keeps ReactNativeFiberHostComponent and NativeMethodsMixin in sync. + * It can also provide types for ReactNative applications that use NMM or refs. */ -var ReactFabricHostComponent = (function() { - function ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ) { - _classCallCheck(this, ReactFabricHostComponent); +/** + * Flat ReactNative renderer bundles are too big for Flow to parse efficiently. + * Provide minimal Flow typing for the high-level RN API and call it a day. + */ - this._nativeTag = tag; - this.viewConfig = viewConfig; - this.currentProps = props; - this._internalInstanceHandle = internalInstanceHandle; - } +var DiscreteEvent = 0; +var UserBlockingEvent = 1; +var ContinuousEvent = 2; - ReactFabricHostComponent.prototype.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); - }; - - ReactFabricHostComponent.prototype.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); - }; - - ReactFabricHostComponent.prototype.measure = function measure(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - - ReactFabricHostComponent.prototype.measureInWindow = function measureInWindow( - callback - ) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ - ReactFabricHostComponent.prototype.measureLayout = function measureLayout( - relativeToNativeNode, - onSuccess, - onFail /* currently unused */ - ) { - if ( - typeof relativeToNativeNode === "number" || - !(relativeToNativeNode instanceof ReactFabricHostComponent) - ) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a ref to a native component." - ); +var warning = warningWithoutStack$1; +{ + warning = function(condition, format) { + if (condition) { return; } + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + // eslint-disable-next-line react-internal/warning-and-invariant-args - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; + for ( + var _len = arguments.length, + args = Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } - ReactFabricHostComponent.prototype.setNativeProps = function setNativeProps( - nativeProps - ) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" + warningWithoutStack$1.apply( + undefined, + [false, format + "%s"].concat(args, [stack]) ); - - return; }; - - return ReactFabricHostComponent; -})(); - -function appendInitialChild(parentInstance, child) { - appendChildNode(parentInstance.node, child.node); } -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = nextReactTag; - nextReactTag += 2; +var warning$1 = warning; - var viewConfig = getViewConfigForType(type); +// Intentionally not named imports because Rollup would use dynamic dispatch for +// CommonJS interop named imports. +var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var runWithPriority = Scheduler.unstable_runWithPriority; +var _nativeFabricUIManage$2 = nativeFabricUIManager; +var measureInWindow = _nativeFabricUIManage$2.measureInWindow; + +var activeTimeouts = new Map(); +var rootEventTypesToEventResponderInstances = new Map(); +var ownershipChangeListeners = new Set(); + +var globalOwner = null; + +var currentTimeStamp = 0; +var currentTimers = new Map(); +var currentInstance = null; +var currentEventQueue = null; +var currentEventQueuePriority = ContinuousEvent; +var currentTimerIDCounter = 0; + +var eventResponderContext = { + dispatchEvent: function(eventProp, eventValue, eventPriority) { + validateResponderContext(); + validateEventValue(eventValue); + if (eventPriority < currentEventQueuePriority) { + currentEventQueuePriority = eventPriority; + } + var responderInstance = currentInstance; + var target = responderInstance.fiber; + var responder = responderInstance.responder; + var listeners = collectListeners(eventProp, responder, target); + if (listeners.length !== 0) { + currentEventQueue.push(createEventQueueItem(eventValue, listeners)); + } + }, + isTargetWithinNode: function(childTarget, parentTarget) { + validateResponderContext(); + var childFiber = getFiberFromTarget(childTarget); + var parentFiber = getFiberFromTarget(parentTarget); - { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); + var node = childFiber; + while (node !== null) { + if (node === parentFiber) { + return true; } + node = node.return; } - } - - var updatePayload = create(props, viewConfig.validAttributes); + return false; + }, + getTargetBoundingRect: function(target, callback) { + measureInWindow(target.node, function(x, y, width, height) { + callback({ + left: x, + right: x + width, + top: y, + bottom: y + height + }); + }); + }, + addRootEventTypes: function(rootEventTypes) { + validateResponderContext(); + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + var eventResponderInstance = currentInstance; + registerRootEventType(rootEventType, eventResponderInstance); + } + }, + removeRootEventTypes: function(rootEventTypes) { + validateResponderContext(); + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; - var node = createNode( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload, // props - internalInstanceHandle // internalInstanceHandle - ); + var rootEventResponders = rootEventTypesToEventResponderInstances.get( + rootEventType + ); + var rootEventTypesSet = currentInstance.rootEventTypes; + if (rootEventTypesSet !== null) { + rootEventTypesSet.delete(rootEventType); + } + if (rootEventResponders !== undefined) { + rootEventResponders.delete(currentInstance); + } + } + }, + setTimeout: function(func, delay) { + validateResponderContext(); + if (currentTimers === null) { + currentTimers = new Map(); + } + var timeout = currentTimers.get(delay); + + var timerId = currentTimerIDCounter++; + if (timeout === undefined) { + var _timers = new Map(); + var _id = setTimeout(function() { + processTimers(_timers, delay); + }, delay); + timeout = { + id: _id, + timers: _timers + }; + currentTimers.set(delay, timeout); + } + timeout.timers.set(timerId, { + instance: currentInstance, + func: func, + id: timerId, + timeStamp: currentTimeStamp + }); + activeTimeouts.set(timerId, timeout); + return timerId; + }, + clearTimeout: function(timerId) { + validateResponderContext(); + var timeout = activeTimeouts.get(timerId); - var component = new ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ); + if (timeout !== undefined) { + var _timers2 = timeout.timers; + _timers2.delete(timerId); + if (_timers2.size === 0) { + clearTimeout(timeout.id); + } + } + }, + getTimeStamp: function() { + validateResponderContext(); + return currentTimeStamp; + } +}; +function createEventQueueItem(value, listeners) { return { - node: node, - canonical: component + value: value, + listeners: listeners }; } -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - (function() { - if (!hostContext.isInAParentText) { - throw ReactError( - "Text strings must be rendered within a component." +function validateEventValue(eventValue) { + if (typeof eventValue === "object" && eventValue !== null) { + var target = eventValue.target, + type = eventValue.type, + _timeStamp = eventValue.timeStamp; + + if (target == null || type == null || _timeStamp == null) { + throw new Error( + 'context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.' ); } - })(); + var showWarning = function(name) { + { + warning$1( + false, + "%s is not available on event objects created from event responder modules (React Flare). " + + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', + name, + name + ); + } + }; + eventValue.preventDefault = function() { + { + showWarning("preventDefault()"); + } + }; + eventValue.stopPropagation = function() { + { + showWarning("stopPropagation()"); + } + }; + eventValue.isDefaultPrevented = function() { + { + showWarning("isDefaultPrevented()"); + } + }; + eventValue.isPropagationStopped = function() { + { + showWarning("isPropagationStopped()"); + } + }; + // $FlowFixMe: we don't need value, Flow thinks we do + Object.defineProperty(eventValue, "nativeEvent", { + get: function() { + { + showWarning("nativeEvent"); + } + } + }); + } +} - var tag = nextReactTag; - nextReactTag += 2; +function getFiberFromTarget(target) { + if (target === null) { + return null; + } + return target.canonical._internalInstanceHandle || null; +} - var node = createNode( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { text: text }, // props - internalInstanceHandle // instance handle - ); +function processTimers(timers, delay) { + var timersArr = Array.from(timers.values()); + currentEventQueuePriority = ContinuousEvent; + try { + for (var i = 0; i < timersArr.length; i++) { + var _timersArr$i = timersArr[i], + _instance = _timersArr$i.instance, + _func = _timersArr$i.func, + _id2 = _timersArr$i.id, + _timeStamp2 = _timersArr$i.timeStamp; + + currentInstance = _instance; + currentEventQueue = []; + currentTimeStamp = _timeStamp2 + delay; + try { + _func(); + } finally { + activeTimeouts.delete(_id2); + } + } + processEventQueue(); + } finally { + currentTimers = null; + currentInstance = null; + currentEventQueue = null; + currentTimeStamp = 0; + } +} +function createFabricResponderEvent(topLevelType, nativeEvent, target) { return { - node: node + nativeEvent: nativeEvent, + responderTarget: target, + target: target, + type: topLevelType }; } -function finalizeInitialChildren( - parentInstance, - type, - props, - rootContainerInstance, - hostContext -) { - return false; -} - -function getRootHostContext(rootContainerInstance) { - return { isInAParentText: false }; +function validateResponderContext() { + (function() { + if (!(currentEventQueue && currentInstance)) { + throw ReactError( + Error( + "An event responder context was used outside of an event cycle. Use context.setTimeout() to use asynchronous responder context outside of event cycle ." + ) + ); + } + })(); } -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; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function processEventQueue() { + var eventQueue = currentEventQueue; + if (eventQueue.length === 0) { + return; + } + switch (currentEventQueuePriority) { + case DiscreteEvent: { + flushDiscreteUpdatesIfNeeded(currentTimeStamp); + discreteUpdates(function() { + batchedEventUpdates(processEvents, eventQueue); + }); + break; + } + case UserBlockingEvent: { + if (enableUserBlockingEvents) { + runWithPriority( + UserBlockingPriority, + batchedEventUpdates.bind(null, processEvents, eventQueue) + ); + } else { + batchedEventUpdates(processEvents, eventQueue); + } + break; + } + case ContinuousEvent: { + batchedEventUpdates(processEvents, eventQueue); + break; + } } } -function getChildHostContextForEventComponent(parentHostContext) { - // TODO: add getChildHostContextForEventComponent implementation - return parentHostContext; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function releaseOwnershipForEventResponderInstance(eventResponderInstance) { + if (globalOwner === eventResponderInstance) { + globalOwner = null; + triggerOwnershipListeners(); + return true; + } + return false; } -function getChildHostContextForEventTarget(parentHostContext, type) { - // TODO: add getChildHostContextForEventTarget implementation - return parentHostContext; -} +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function collectListeners(eventProp, eventResponder, target) { + var eventListeners = []; + var node = target.return; + nodeTraversal: while (node !== null) { + switch (node.tag) { + case HostComponent: { + var dependencies = node.dependencies; -function getPublicInstance(instance) { - return instance.canonical; -} + if (dependencies !== null) { + var respondersMap = dependencies.responders; -function prepareForCommit(containerInfo) { - // Noop -} - -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. - instance.canonical.currentProps = newProps; - return updatePayload; -} - -function resetAfterCommit(containerInfo) { - // Noop -} - -function shouldDeprioritizeSubtree(type, props) { - return false; -} - -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 isPrimaryRenderer = false; + if (respondersMap !== null && respondersMap.has(eventResponder)) { + break nodeTraversal; + } + } + break; + } + case FunctionComponent: + case MemoComponent: + case ForwardRef: { + var _dependencies = node.dependencies; -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; + if (_dependencies !== null) { + var _listeners = _dependencies.listeners; -// ------------------- -// Persistence -// ------------------- + if (_listeners !== null) { + for ( + var s = 0, listenersLength = _listeners.length; + s < listenersLength; + s++ + ) { + var listener = _listeners[s]; + var responder = listener.responder, + props = listener.props; -var supportsPersistence = true; + var listenerFunc = props[eventProp]; -function cloneInstance( - instance, - updatePayload, - type, - oldProps, - newProps, - internalInstanceHandle, - keepChildren, - recyclableInstance -) { - var node = instance.node; - var clone = void 0; - 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); + if ( + responder === eventResponder && + typeof listenerFunc === "function" + ) { + eventListeners.push(listenerFunc); + } + } + } + } + } } + node = node.return; } - 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); + return eventListeners; } -function appendChildToContainerChildSet(childSet, child) { - appendChildNodeToSet(childSet, child.node); -} +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function processEvents(eventQueue) { + for (var i = 0, length = eventQueue.length; i < length; i++) { + var _eventQueue$i = eventQueue[i], + _value = _eventQueue$i.value, + _listeners2 = _eventQueue$i.listeners; -function finalizeContainerChildren(container, newChildren) { - completeRoot(container, newChildren); + for (var s = 0, length2 = _listeners2.length; s < length2; s++) { + var listener = _listeners2[s]; + var type = + typeof _value === "object" && _value !== null ? _value.type : ""; + invokeGuardedCallbackAndCatchFirstError( + type, + listener, + undefined, + _value + ); + } + } } -function mountEventComponent(eventComponentInstance) { - throw new Error("Not yet implemented."); +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function responderEventTypesContainType(eventTypes, type) { + for (var i = 0, len = eventTypes.length; i < len; i++) { + if (eventTypes[i] === type) { + return true; + } + } + return false; } -function updateEventComponent(eventComponentInstance) { - throw new Error("Not yet implemented."); -} +function validateResponderTargetEventTypes(eventType, responder) { + var targetEventTypes = responder.targetEventTypes; + // Validate the target event type exists on the responder -function unmountEventComponent(eventComponentInstance) { - throw new Error("Not yet implemented."); + if (targetEventTypes !== null) { + return responderEventTypesContainType(targetEventTypes, eventType); + } + return false; } -function getEventTargetChildElement(type, props) { - throw new Error("Not yet implemented."); +function validateOwnership(responderInstance) { + return globalOwner === null || globalOwner === responderInstance; } -function handleEventTarget( - type, - props, - rootContainerInstance, - internalInstanceHandle +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function traverseAndHandleEventResponderInstances( + eventType, + targetFiber, + nativeEvent ) { - throw new Error("Not yet implemented."); -} + // Trigger event responders in this order: + // - Bubble target responder phase + // - Root responder phase -function commitEventTarget(type, props, instance, parentInstance) { - throw new Error("Not yet implemented."); -} - -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; + var responderEvent = createFabricResponderEvent( + eventType, + nativeEvent, + targetFiber !== null ? targetFiber.stateNode : null + ); + var visitedResponders = new Set(); + var node = targetFiber; + while (node !== null) { + var _node = node, + dependencies = _node.dependencies, + tag = _node.tag; + + if (tag === HostComponent && dependencies !== null) { + var respondersMap = dependencies.responders; + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + + if (validateOwnership(responderInstance)) { + var props = responderInstance.props, + responder = responderInstance.responder, + state = responderInstance.state, + target = responderInstance.target; -var describeComponentFrame = function(name, source, ownerName) { - var sourceInfo = ""; - 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; + if ( + !visitedResponders.has(responder) && + validateResponderTargetEventTypes(eventType, responder) + ) { + var onEvent = responder.onEvent; + visitedResponders.add(responder); + if (onEvent !== null) { + currentInstance = responderInstance; + responderEvent.responderTarget = target; + onEvent(responderEvent, eventResponderContext, props, state); + } + } } } } } - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; + node = node.return; } - return "\n in " + (name || "Unknown") + sourceInfo; -}; + // Root phase + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + eventType + ); + if (rootEventResponderInstances !== undefined) { + var _responderInstances = Array.from(rootEventResponderInstances); -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + for (var _i = 0; _i < _responderInstances.length; _i++) { + var _responderInstance = _responderInstances[_i]; + if (!validateOwnership(_responderInstance)) { + continue; + } + var _props = _responderInstance.props, + _responder = _responderInstance.responder, + _state = _responderInstance.state, + _target = _responderInstance.target; -function describeFiber(fiber) { - switch (fiber.tag) { - case HostRoot: - case HostPortal: - case HostText: - case Fragment: - case ContextProvider: - case ContextConsumer: - return ""; - default: - var owner = fiber._debugOwner; - var source = fiber._debugSource; - var name = getComponentName(fiber.type); - var ownerName = null; - if (owner) { - ownerName = getComponentName(owner.type); + var onRootEvent = _responder.onRootEvent; + if (onRootEvent !== null) { + currentInstance = _responderInstance; + responderEvent.responderTarget = _target; + onRootEvent(responderEvent, eventResponderContext, _props, _state); } - return describeComponentFrame(name, source, ownerName); + } } } -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - var node = workInProgress; - do { - info += describeFiber(node); - node = node.return; - } while (node); - return info; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function dispatchEventForResponderEventSystem( + topLevelType, + targetFiber, + nativeEvent +) { + var previousEventQueue = currentEventQueue; + var previousInstance = currentInstance; + var previousTimers = currentTimers; + var previousTimeStamp = currentTimeStamp; + var previousEventQueuePriority = currentEventQueuePriority; + currentTimers = null; + currentEventQueue = []; + currentEventQueuePriority = ContinuousEvent; + // We might want to control timeStamp another way here + currentTimeStamp = Date.now(); + try { + traverseAndHandleEventResponderInstances( + topLevelType, + targetFiber, + nativeEvent + ); + processEventQueue(); + } finally { + currentTimers = previousTimers; + currentInstance = previousInstance; + currentEventQueue = previousEventQueue; + currentTimeStamp = previousTimeStamp; + currentEventQueuePriority = previousEventQueuePriority; + } } -var current = null; -var phase = null; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function triggerOwnershipListeners() { + var listeningInstances = Array.from(ownershipChangeListeners); + var previousInstance = currentInstance; + var previousEventQueuePriority = currentEventQueuePriority; + var previousEventQueue = currentEventQueue; + try { + for (var i = 0; i < listeningInstances.length; i++) { + var _instance2 = listeningInstances[i]; + var props = _instance2.props, + responder = _instance2.responder, + state = _instance2.state; -function getCurrentFiberOwnerNameInDevOrNull() { - { - if (current === null) { - return null; - } - var owner = current._debugOwner; - if (owner !== null && typeof owner !== "undefined") { - return getComponentName(owner.type); + currentInstance = _instance2; + currentEventQueuePriority = ContinuousEvent; + currentEventQueue = []; + var onOwnershipChange = responder.onOwnershipChange; + if (onOwnershipChange !== null) { + onOwnershipChange(eventResponderContext, props, state); + } } + processEventQueue(); + } finally { + currentInstance = previousInstance; + currentEventQueue = previousEventQueue; + currentEventQueuePriority = previousEventQueuePriority; } - return null; } -function getCurrentFiberStackInDev() { - { - if (current === null) { - return ""; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function mountEventResponder(responder, responderInstance, props, state) { + if (responder.onOwnershipChange !== null) { + ownershipChangeListeners.add(responderInstance); + } + var onMount = responder.onMount; + if (onMount !== null) { + currentEventQueuePriority = ContinuousEvent; + currentInstance = responderInstance; + currentEventQueue = []; + try { + onMount(eventResponderContext, props, state); + processEventQueue(); + } finally { + currentEventQueue = null; + currentInstance = null; + currentTimers = null; } - // Safe because if current fiber exists, we are reconciling, - // and it is guaranteed to be the work-in-progress version. - return getStackByFiberInDevAndProd(current); } - return ""; } -function resetCurrentFiber() { - { - ReactDebugCurrentFrame.getCurrentStack = null; - current = null; - phase = null; - } -} +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function unmountEventResponder(responderInstance) { + var responder = responderInstance.responder; + var onUnmount = responder.onUnmount; + if (onUnmount !== null) { + var props = responderInstance.props, + state = responderInstance.state; -function setCurrentFiber(fiber) { - { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; - current = fiber; - phase = null; + currentEventQueue = []; + currentEventQueuePriority = ContinuousEvent; + currentInstance = responderInstance; + try { + onUnmount(eventResponderContext, props, state); + processEventQueue(); + } finally { + currentEventQueue = null; + currentInstance = null; + currentTimers = null; + } } -} + releaseOwnershipForEventResponderInstance(responderInstance); + if (responder.onOwnershipChange !== null) { + ownershipChangeListeners.delete(responderInstance); + } + var rootEventTypesSet = responderInstance.rootEventTypes; + if (rootEventTypesSet !== null) { + var rootEventTypes = Array.from(rootEventTypesSet); -function setCurrentPhase(lifeCyclePhase) { - { - phase = lifeCyclePhase; + for (var i = 0; i < rootEventTypes.length; i++) { + var topLevelEventType = rootEventTypes[i]; + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + topLevelEventType + ); + if (rootEventResponderInstances !== undefined) { + rootEventResponderInstances.delete(responderInstance); + } + } } } -// Prefix measurements so that it's possible to filter them. -// Longer prefixes are hard to read in DevTools. +function registerRootEventType(rootEventType, responderInstance) { + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + rootEventType + ); + if (rootEventResponderInstances === undefined) { + rootEventResponderInstances = new Set(); + rootEventTypesToEventResponderInstances.set( + rootEventType, + rootEventResponderInstances + ); + } + var rootEventTypesSet = responderInstance.rootEventTypes; + if (rootEventTypesSet === null) { + rootEventTypesSet = responderInstance.rootEventTypes = new Set(); + } + (function() { + if (!!rootEventTypesSet.has(rootEventType)) { + throw ReactError( + Error( + 'addRootEventTypes() found a duplicate root event type of "' + + rootEventType + + '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.' + ) + ); + } + })(); + rootEventTypesSet.add(rootEventType); + rootEventResponderInstances.add(responderInstance); +} + +function addRootEventTypesForResponderInstance( + responderInstance, + rootEventTypes +) { + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + registerRootEventType(rootEventType, responderInstance); + } +} + +function dispatchEvent(target, topLevelType, nativeEvent) { + var targetFiber = target; + if (enableFlareAPI) { + // React Flare event system + dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent); + } + batchedUpdates(function() { + // Heritage plugin event system + runExtractedPluginEventsInBatch( + topLevelType, + targetFiber, + nativeEvent, + nativeEvent.target + ); + }); + // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. +} + +// Renderers that don't support mutation +// can re-export everything from this module. + +function shim() { + (function() { + { + throw ReactError( + 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) +var supportsMutation = false; +var appendChild = shim; +var appendChildToContainer = shim; +var commitTextUpdate = shim; +var commitMount = shim; +var commitUpdate = shim; +var insertBefore = shim; +var insertInContainerBefore = shim; +var removeChild = shim; +var removeChildFromContainer = shim; +var resetTextContent = shim; +var hideInstance = shim; +var hideTextInstance = shim; +var unhideInstance = shim; +var unhideTextInstance = shim; + +// Renderers that don't support hydration +// can re-export everything from this module. + +function shim$1() { + (function() { + { + throw ReactError( + 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 supportsHydration = false; +var canHydrateInstance = shim$1; +var canHydrateTextInstance = shim$1; +var canHydrateSuspenseInstance = shim$1; +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var registerSuspenseInstanceRetry = shim$1; +var getNextHydratableSibling = shim$1; +var getFirstHydratableChild = shim$1; +var hydrateInstance = shim$1; +var hydrateTextInstance = shim$1; +var getNextHydratableInstanceAfterSuspenseInstance = shim$1; +var clearSuspenseBoundary = shim$1; +var clearSuspenseBoundaryFromContainer = shim$1; +var didNotMatchHydratedContainerTextInstance = shim$1; +var didNotMatchHydratedTextInstance = shim$1; +var didNotHydrateContainerInstance = shim$1; +var didNotHydrateInstance = shim$1; +var didNotFindHydratableContainerInstance = shim$1; +var didNotFindHydratableContainerTextInstance = shim$1; +var didNotFindHydratableContainerSuspenseInstance = shim$1; +var didNotFindHydratableInstance = shim$1; +var didNotFindHydratableTextInstance = shim$1; +var didNotFindHydratableSuspenseInstance = shim$1; + +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +} + +// Modules provided by RN: +var _nativeFabricUIManage$1 = nativeFabricUIManager; +var createNode = _nativeFabricUIManage$1.createNode; +var cloneNode = _nativeFabricUIManage$1.cloneNode; +var cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren; +var cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps; +var cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps; +var createChildNodeSet = _nativeFabricUIManage$1.createChildSet; +var appendChildNode = _nativeFabricUIManage$1.appendChild; +var appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet; +var completeRoot = _nativeFabricUIManage$1.completeRoot; +var registerEventHandler = _nativeFabricUIManage$1.registerEventHandler; +var fabricMeasure = _nativeFabricUIManage$1.measure; +var fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow; +var fabricMeasureLayout = _nativeFabricUIManage$1.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. + +var nextReactTag = 2; + +// 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. + */ + +var ReactFabricHostComponent = (function() { + function ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle + ) { + _classCallCheck(this, ReactFabricHostComponent); + + this._nativeTag = tag; + this.viewConfig = viewConfig; + this.currentProps = props; + this._internalInstanceHandle = internalInstanceHandle; + } + + ReactFabricHostComponent.prototype.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + }; + + ReactFabricHostComponent.prototype.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + }; + + ReactFabricHostComponent.prototype.measure = function measure(callback) { + fabricMeasure( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + + ReactFabricHostComponent.prototype.measureInWindow = function measureInWindow( + callback + ) { + fabricMeasureInWindow( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + + ReactFabricHostComponent.prototype.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail /* currently unused */ + ) { + if ( + typeof relativeToNativeNode === "number" || + !(relativeToNativeNode instanceof ReactFabricHostComponent) + ) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + + return; + } + + fabricMeasureLayout( + this._internalInstanceHandle.stateNode.node, + relativeToNativeNode._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + + ReactFabricHostComponent.prototype.setNativeProps = function setNativeProps( + nativeProps + ) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + + return; + }; + + return ReactFabricHostComponent; +})(); + +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 +) { + (function() { + if (!hostContext.isInAParentText) { + throw ReactError( + 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 finalizeInitialChildren( + parentInstance, + type, + props, + rootContainerInstance, + hostContext +) { + 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"; + + if (prevIsInAParentText !== isInAParentText) { + return { isInAParentText: isInAParentText }; + } else { + return parentHostContext; + } +} + +function getPublicInstance(instance) { + return instance.canonical; +} + +function prepareForCommit(containerInfo) { + // Noop +} + +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. + instance.canonical.currentProps = newProps; + return updatePayload; +} + +function resetAfterCommit(containerInfo) { + // Noop +} + +function shouldDeprioritizeSubtree(type, props) { + return false; +} + +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 isPrimaryRenderer = false; + +// The Fabric renderer shouldn't trigger missing act() warnings +var warnsIfNotActing = false; + +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; + +// ------------------- +// Persistence +// ------------------- + +var supportsPersistence = true; + +function cloneInstance( + instance, + updatePayload, + type, + oldProps, + newProps, + internalInstanceHandle, + keepChildren, + recyclableInstance +) { + var node = instance.node; + var clone = void 0; + 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 mountResponderInstance( + responder, + responderInstance, + props, + state, + instance, + rootContainerInstance +) { + if (enableFlareAPI) { + var rootEventTypes = responder.rootEventTypes; + + if (rootEventTypes !== null) { + addRootEventTypesForResponderInstance(responderInstance, rootEventTypes); + } + mountEventResponder(responder, responderInstance, props, state); + } +} + +function unmountResponderInstance(responderInstance) { + if (enableFlareAPI) { + // TODO stop listening to targetEventTypes + unmountEventResponder(responderInstance); + } +} + +function getFundamentalComponentInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function mountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function shouldUpdateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function updateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function unmountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function cloneFundamentalInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; + +var describeComponentFrame = function(name, source, ownerName) { + var sourceInfo = ""; + 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 + ")"; + } + return "\n in " + (name || "Unknown") + sourceInfo; +}; + +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + +function describeFiber(fiber) { + switch (fiber.tag) { + case HostRoot: + case HostPortal: + case HostText: + case Fragment: + case ContextProvider: + case ContextConsumer: + return ""; + default: + var owner = fiber._debugOwner; + var source = fiber._debugSource; + var name = getComponentName(fiber.type); + var ownerName = null; + if (owner) { + ownerName = getComponentName(owner.type); + } + return describeComponentFrame(name, source, ownerName); + } +} + +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + var node = workInProgress; + do { + info += describeFiber(node); + node = node.return; + } while (node); + return info; +} + +var current = null; +var phase = null; + +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } + var owner = current._debugOwner; + if (owner !== null && typeof owner !== "undefined") { + return getComponentName(owner.type); + } + } + return null; +} + +function getCurrentFiberStackInDev() { + { + if (current === null) { + return ""; + } + // Safe because if current fiber exists, we are reconciling, + // and it is guaranteed to be the work-in-progress version. + return getStackByFiberInDevAndProd(current); + } + return ""; +} + +function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + phase = null; + } +} + +function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; + current = fiber; + phase = null; + } +} + +function setCurrentPhase(lifeCyclePhase) { + { + phase = lifeCyclePhase; + } +} + +// Prefix measurements so that it's possible to filter them. +// Longer prefixes are hard to read in DevTools. var reactEmoji = "\u269B"; var warningEmoji = "\u26D4"; var supportsUserTiming = @@ -4857,7 +5735,9 @@ function pushTopLevelContextObject(fiber, context, didChange) { (function() { if (!(contextStackCursor.current === emptyContextObject)) { throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -4905,10 +5785,12 @@ function processChildContext(fiber, type, parentContext) { (function() { if (!(contextKey in childContextTypes)) { throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); } })(); @@ -4959,7 +5841,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { (function() { if (!instance) { throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -4986,162 +5870,50 @@ function invalidateContextProvider(workInProgress, type, didChange) { pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -} - -function findCurrentUnmaskedContext(fiber) { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - (function() { - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw ReactError( - "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); - (function() { - { - throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); -} - -var onCommitFiberRoot = null; -var onCommitFiberUnmount = null; -var hasLoggedError = false; - -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); - } - } - }; -} - -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; - -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; - } - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - 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) { - { - warningWithoutStack$1( - false, - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://fb.me/react-devtools" - ); - } - // DevTools exists, even though it doesn't support Fiber. - return true; - } - try { - var rendererID = hook.inject(internals); - // We have successfully injected, so now it is safe to set up hooks. - onCommitFiberRoot = catchErrors(function(root) { - var didError = (root.current.effectTag & DidCapture) === DidCapture; - hook.onCommitFiberRoot(rendererID, root, undefined, didError); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); - } - } - // DevTools exists - return true; -} - -function onCommitRoot(root) { - if (typeof onCommitFiberRoot === "function") { - onCommitFiberRoot(root); - } -} - -function onCommitUnmount(fiber) { - if (typeof onCommitFiberUnmount === "function") { - onCommitFiberUnmount(fiber); - } -} - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = warningWithoutStack$1; +} -{ - warning = function(condition, format) { - if (condition) { - return; +function findCurrentUnmaskedContext(fiber) { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + (function() { + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw ReactError( + 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 ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); - // eslint-disable-next-line react-internal/warning-and-invariant-args + })(); - for ( - var _len = arguments.length, - args = Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; + 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; + } } - - warningWithoutStack$1.apply( - undefined, - [false, format + "%s"].concat(args, [stack]) - ); - }; + node = node.return; + } while (node !== null); + (function() { + { + throw ReactError( + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) + ); + } + })(); } -var warning$1 = warning; +var LegacyRoot = 0; +var BatchedRoot = 1; +var ConcurrentRoot = 2; // Intentionally not named imports because Rollup would use dynamic dispatch for // CommonJS interop named imports. @@ -5149,6 +5921,7 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority; var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback; var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback; var Scheduler_shouldYield = Scheduler.unstable_shouldYield; +var Scheduler_requestPaint = Scheduler.unstable_requestPaint; var Scheduler_now = Scheduler.unstable_now; var Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel; @@ -5170,7 +5943,9 @@ if (enableSchedulerTracing) { ) ) { throw ReactError( - "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 http://fb.me/react-profiling" + 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 http://fb.me/react-profiling" + ) ); } })(); @@ -5182,21 +5957,20 @@ var fakeCallbackNode = {}; // 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 UserBlockingPriority$1 = 98; var NormalPriority = 97; var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. -var shouldYield = disableYielding - ? function() { - return false; - } // Never yield when `disableYielding` is on - : Scheduler_shouldYield; +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 immediateQueue = null; +var syncQueue = null; var immediateQueueCallbackNode = null; -var isFlushingImmediate = false; +var isFlushingSyncQueue = false; var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. @@ -5218,7 +5992,7 @@ function getCurrentPriorityLevel() { case Scheduler_ImmediatePriority: return ImmediatePriority; case Scheduler_UserBlockingPriority: - return UserBlockingPriority; + return UserBlockingPriority$1; case Scheduler_NormalPriority: return NormalPriority; case Scheduler_LowPriority: @@ -5228,7 +6002,7 @@ function getCurrentPriorityLevel() { default: (function() { { - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } })(); } @@ -5238,7 +6012,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { switch (reactPriorityLevel) { case ImmediatePriority: return Scheduler_ImmediatePriority; - case UserBlockingPriority: + case UserBlockingPriority$1: return Scheduler_UserBlockingPriority; case NormalPriority: return Scheduler_NormalPriority; @@ -5249,88 +6023,94 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { default: (function() { { - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } })(); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(priorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (reactPriorityLevel === ImmediatePriority) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushImmediateQueue`. - if (immediateQueue === null) { - immediateQueue = [callback]; - // Flush the queue in the next tick, at the earliest. - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ); - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - immediateQueue.push(callback); - } - return fakeCallbackNode; - } - // Otherwise pass through to Scheduler. 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 flushImmediateQueue() { +function flushSyncCallbackQueue() { if (immediateQueueCallbackNode !== null) { Scheduler_cancelCallback(immediateQueueCallbackNode); } - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && immediateQueue !== null) { +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. - isFlushingImmediate = true; + isFlushingSyncQueue = true; var i = 0; try { var _isSync = true; - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do { - callback = callback(_isSync); - } while (callback !== null); - } - immediateQueue = null; + var queue = syncQueue; + runWithPriority$1(ImmediatePriority, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do { + callback = callback(_isSync); + } while (callback !== null); + } + }); + syncQueue = null; } catch (error) { // If something throws, leave the remaining callbacks on the queue. - if (immediateQueue !== null) { - immediateQueue = immediateQueue.slice(i + 1); + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); } // Resume flushing in the next tick Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ); throw error; } finally { - isFlushingImmediate = false; + isFlushingSyncQueue = false; } } } -var NoContext = 0; -var ConcurrentMode = 1; -var StrictMode = 2; -var ProfileMode = 4; +var NoMode = 0; +var StrictMode = 1; +// TODO: Remove BatchedMode and ConcurrentMode by reading from the root +// tag instead +var BatchedMode = 2; +var ConcurrentMode = 4; +var ProfileMode = 8; // Max 31 bit integer. The max integer size in V8 for 32-bit systems. // Math.pow(2, 30) - 1 @@ -5340,9 +6120,10 @@ var MAX_SIGNED_31_BIT_INT = 1073741823; var NoWork = 0; var Never = 1; var Sync = MAX_SIGNED_31_BIT_INT; +var Batched = Sync - 1; var UNIT_SIZE = 10; -var MAGIC_NUMBER_OFFSET = MAX_SIGNED_31_BIT_INT - 1; +var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms. function msToExpirationTime(ms) { @@ -5381,10 +6162,13 @@ function computeAsyncExpiration(currentTime) { ); } -// Same as computeAsyncExpiration but without the bucketing logic. This is -// used to compute timestamps instead of actual expiration times. -function computeAsyncExpirationNoBucket(currentTime) { - return currentTime - LOW_PRIORITY_EXPIRATION / UNIT_SIZE; +function computeSuspenseExpiration(currentTime, timeoutMs) { + // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time? + return computeExpirationBucket( + currentTime, + timeoutMs, + LOW_PRIORITY_BATCH_SIZE + ); } // We intentionally set a higher expiration time for interactive updates in @@ -5422,7 +6206,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return ImmediatePriority; } if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) { - return UserBlockingPriority; + return UserBlockingPriority$1; } if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) { return NormalPriority; @@ -5556,332 +6340,754 @@ var lowPriorityWarning = function() {}; var lowPriorityWarning$1 = lowPriorityWarning; var ReactStrictModeWarnings = { - discardPendingWarnings: function() {}, - flushPendingDeprecationWarnings: function() {}, - flushPendingUnsafeLifecycleWarnings: function() {}, - recordDeprecationWarnings: function(fiber, instance) {}, recordUnsafeLifecycleWarnings: function(fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function() {}, recordLegacyContextWarning: function(fiber, instance) {}, - flushLegacyContextWarning: function() {} + flushLegacyContextWarning: function() {}, + discardPendingWarnings: function() {} }; { - var LIFECYCLE_SUGGESTIONS = { - UNSAFE_componentWillMount: "componentDidMount", - UNSAFE_componentWillReceiveProps: "static getDerivedStateFromProps", - UNSAFE_componentWillUpdate: "componentDidUpdate" + var findStrictRoot = function(fiber) { + var maybeStrictRoot = null; + + var node = fiber; + while (node !== null) { + if (node.mode & StrictMode) { + maybeStrictRoot = node; + } + node = node.return; + } + + return maybeStrictRoot; + }; + + var setToSortedString = function(set) { + var array = []; + set.forEach(function(value) { + array.push(value); + }); + return array.sort().join(", "); + }; + + var pendingComponentWillMountWarnings = []; + var pendingUNSAFE_ComponentWillMountWarnings = []; + var pendingComponentWillReceivePropsWarnings = []; + var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + var pendingComponentWillUpdateWarnings = []; + var pendingUNSAFE_ComponentWillUpdateWarnings = []; + + // Tracks components we have already warned about. + var didWarnAboutUnsafeLifecycles = new Set(); + + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( + fiber, + instance + ) { + // Dedup strategy: Warn once per component. + if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { + return; + } + + if ( + typeof instance.componentWillMount === "function" && + // Don't warn about react-lifecycles-compat polyfilled components. + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + pendingComponentWillMountWarnings.push(fiber); + } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillMount === "function" + ) { + pendingUNSAFE_ComponentWillMountWarnings.push(fiber); + } + + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== true + ) { + pendingComponentWillReceivePropsWarnings.push(fiber); + } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); + } + + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + pendingComponentWillUpdateWarnings.push(fiber); + } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); + } + }; + + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { + // We do an initial pass to gather component names + var componentWillMountUniqueNames = new Set(); + if (pendingComponentWillMountWarnings.length > 0) { + pendingComponentWillMountWarnings.forEach(function(fiber) { + componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillMountWarnings = []; + } + + var UNSAFE_componentWillMountUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { + pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { + UNSAFE_componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillMountWarnings = []; + } + + var componentWillReceivePropsUniqueNames = new Set(); + if (pendingComponentWillReceivePropsWarnings.length > 0) { + pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { + componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingComponentWillReceivePropsWarnings = []; + } + + var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { + UNSAFE_componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + } + + var componentWillUpdateUniqueNames = new Set(); + if (pendingComponentWillUpdateWarnings.length > 0) { + pendingComponentWillUpdateWarnings.forEach(function(fiber) { + componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingComponentWillUpdateWarnings = []; + } + + var UNSAFE_componentWillUpdateUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { + pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { + UNSAFE_componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingUNSAFE_ComponentWillUpdateWarnings = []; + } + + // Finally, we flush all the warnings + // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' + if (UNSAFE_componentWillMountUniqueNames.size > 0) { + var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "\nPlease update the following components: %s", + sortedNames + ); + } + + if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames = setToSortedString( + UNSAFE_componentWillReceivePropsUniqueNames + ); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, " + + "refactor your code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" + + "\nPlease update the following components: %s", + _sortedNames + ); + } + + if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { + var _sortedNames2 = setToSortedString( + UNSAFE_componentWillUpdateUniqueNames + ); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "\nPlease update the following components: %s", + _sortedNames2 + ); + } + + if (componentWillMountUniqueNames.size > 0) { + var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); + + lowPriorityWarning$1( + false, + "componentWillMount has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames3 + ); + } + + if (componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames4 = setToSortedString( + componentWillReceivePropsUniqueNames + ); + + lowPriorityWarning$1( + false, + "componentWillReceiveProps has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, refactor your " + + "code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" + + "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames4 + ); + } + + if (componentWillUpdateUniqueNames.size > 0) { + var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); + + lowPriorityWarning$1( + false, + "componentWillUpdate has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames5 + ); + } + }; + + var pendingLegacyContextWarning = new Map(); + + // Tracks components we have already warned about. + var didWarnAboutLegacyContext = new Set(); + + ReactStrictModeWarnings.recordLegacyContextWarning = function( + fiber, + instance + ) { + var strictRoot = findStrictRoot(fiber); + if (strictRoot === null) { + warningWithoutStack$1( + false, + "Expected to find a StrictMode component in a strict mode tree. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + return; + } + + // Dedup strategy: Warn once per component. + if (didWarnAboutLegacyContext.has(fiber.type)) { + return; + } + + var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); + + if ( + fiber.type.contextTypes != null || + fiber.type.childContextTypes != null || + (instance !== null && typeof instance.getChildContext === "function") + ) { + if (warningsForRoot === undefined) { + warningsForRoot = []; + pendingLegacyContextWarning.set(strictRoot, warningsForRoot); + } + warningsForRoot.push(fiber); + } }; - var pendingComponentWillMountWarnings = []; - var pendingComponentWillReceivePropsWarnings = []; - var pendingComponentWillUpdateWarnings = []; - var pendingUnsafeLifecycleWarnings = new Map(); - var pendingLegacyContextWarning = new Map(); + ReactStrictModeWarnings.flushLegacyContextWarning = function() { + pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { + var uniqueNames = new Set(); + fiberArray.forEach(function(fiber) { + uniqueNames.add(getComponentName(fiber.type) || "Component"); + didWarnAboutLegacyContext.add(fiber.type); + }); - // Tracks components we have already warned about. - var didWarnAboutDeprecatedLifecycles = new Set(); - var didWarnAboutUnsafeLifecycles = new Set(); - var didWarnAboutLegacyContext = new Set(); + var sortedNames = setToSortedString(uniqueNames); + var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - var setToSortedString = function(set) { - var array = []; - set.forEach(function(value) { - array.push(value); + warningWithoutStack$1( + false, + "Legacy context API has been detected within a strict-mode tree: %s" + + "\n\nThe old API will be supported in all 16.x releases, but applications " + + "using it should migrate to the new version." + + "\n\nPlease update the following components: %s" + + "\n\nLearn more about this warning here:" + + "\nhttps://fb.me/react-legacy-context", + strictRootComponentStack, + sortedNames + ); }); - return array.sort().join(", "); }; ReactStrictModeWarnings.discardPendingWarnings = function() { pendingComponentWillMountWarnings = []; + pendingUNSAFE_ComponentWillMountWarnings = []; pendingComponentWillReceivePropsWarnings = []; + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; pendingComponentWillUpdateWarnings = []; - pendingUnsafeLifecycleWarnings = new Map(); + pendingUNSAFE_ComponentWillUpdateWarnings = []; pendingLegacyContextWarning = new Map(); }; +} - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { - pendingUnsafeLifecycleWarnings.forEach(function( - lifecycleWarningsMap, - strictRoot - ) { - var lifecyclesWarningMessages = []; - - Object.keys(lifecycleWarningsMap).forEach(function(lifecycle) { - var lifecycleWarnings = lifecycleWarningsMap[lifecycle]; - if (lifecycleWarnings.length > 0) { - var componentNames = new Set(); - lifecycleWarnings.forEach(function(fiber) { - componentNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - - var formatted = lifecycle.replace("UNSAFE_", ""); - var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle]; - var sortedComponentNames = setToSortedString(componentNames); - - lifecyclesWarningMessages.push( - formatted + - ": Please update the following components to use " + - (suggestion + " instead: " + sortedComponentNames) - ); - } - }); +// Resolves type to a family. - if (lifecyclesWarningMessages.length > 0) { - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); +// Used by React Refresh runtime through DevTools Global Hook. - warningWithoutStack$1( - false, - "Unsafe lifecycle methods were found within a strict-mode tree:%s" + - "\n\n%s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-strict-mode-warnings", - strictRootComponentStack, - lifecyclesWarningMessages.join("\n\n") - ); - } - }); +var resolveFamily = null; +// $FlowFixMe Flow gets confused by a WeakSet feature check below. +var failedBoundaries = null; - pendingUnsafeLifecycleWarnings = new Map(); - }; +var setRefreshHandler = function(handler) { + { + resolveFamily = handler; + } +}; - var findStrictRoot = function(fiber) { - var maybeStrictRoot = null; +function resolveFunctionForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + var family = resolveFamily(type); + if (family === undefined) { + return type; + } + // Use the latest known implementation. + return family.current; + } +} - var node = fiber; - while (node !== null) { - if (node.mode & StrictMode) { - maybeStrictRoot = node; +function resolveClassForHotReloading(type) { + // No implementation differences. + return resolveFunctionForHotReloading(type); +} + +function resolveForwardRefForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + var family = resolveFamily(type); + if (family === undefined) { + // Check if we're dealing with a real forwardRef. Don't want to crash early. + if ( + type !== null && + type !== undefined && + typeof type.render === "function" + ) { + // ForwardRef is special because its resolved .type is an object, + // but it's possible that we only have its inner render function in the map. + // If that inner render function is different, we'll build a new forwardRef type. + var currentRender = resolveFunctionForHotReloading(type.render); + if (type.render !== currentRender) { + var syntheticType = { + $$typeof: REACT_FORWARD_REF_TYPE, + render: currentRender + }; + if (type.displayName !== undefined) { + syntheticType.displayName = type.displayName; + } + return syntheticType; + } } - node = node.return; + return type; } + // Use the latest known implementation. + return family.current; + } +} - return maybeStrictRoot; - }; +function isCompatibleFamilyForHotReloading(fiber, element) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return false; + } - ReactStrictModeWarnings.flushPendingDeprecationWarnings = function() { - if (pendingComponentWillMountWarnings.length > 0) { - var uniqueNames = new Set(); - pendingComponentWillMountWarnings.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); + var prevType = fiber.elementType; + var nextType = element.type; - var sortedNames = setToSortedString(uniqueNames); + // If we got here, we know types aren't === equal. + var needsCompareFamilies = false; - lowPriorityWarning$1( - false, - "componentWillMount is deprecated and will be removed in the next major version. " + - "Use componentDidMount instead. As a temporary workaround, " + - "you can rename to UNSAFE_componentWillMount." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - sortedNames - ); + var $$typeofNextType = + typeof nextType === "object" && nextType !== null + ? nextType.$$typeof + : null; - pendingComponentWillMountWarnings = []; + switch (fiber.tag) { + case ClassComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } + break; + } + case FunctionComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + // We don't know the inner type yet. + // We're going to assume that the lazy inner type is stable, + // and so it is sufficient to avoid reconciling it away. + // We're not going to unwrap or actually use the new lazy type. + needsCompareFamilies = true; + } + break; + } + case ForwardRef: { + if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + break; + } + case MemoComponent: + case SimpleMemoComponent: { + if ($$typeofNextType === REACT_MEMO_TYPE) { + // TODO: if it was but can no longer be simple, + // we shouldn't set this. + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + break; + } + default: + return false; } - if (pendingComponentWillReceivePropsWarnings.length > 0) { - var _uniqueNames = new Set(); - pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { - _uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); - - var _sortedNames = setToSortedString(_uniqueNames); + // Check if both types have a family and it's the same one. + if (needsCompareFamilies) { + // Note: memo() and forwardRef() we'll compare outer rather than inner type. + // This means both of them need to be registered to preserve state. + // If we unwrapped and compared the inner types for wrappers instead, + // then we would risk falsely saying two separate memo(Foo) + // calls are equivalent because they wrap the same Foo function. + var prevFamily = resolveFamily(prevType); + if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { + return true; + } + } + return false; + } +} - lowPriorityWarning$1( - false, - "componentWillReceiveProps is deprecated and will be removed in the next major version. " + - "Use static getDerivedStateFromProps instead." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - _sortedNames - ); +function markFailedErrorBoundaryForHotReloading(fiber) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + if (typeof WeakSet !== "function") { + return; + } + if (failedBoundaries === null) { + failedBoundaries = new WeakSet(); + } + failedBoundaries.add(fiber); + } +} - pendingComponentWillReceivePropsWarnings = []; +var scheduleRefresh = function(root, update) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; } + var _staleFamilies = update.staleFamilies, + _updatedFamilies = update.updatedFamilies; - if (pendingComponentWillUpdateWarnings.length > 0) { - var _uniqueNames2 = new Set(); - pendingComponentWillUpdateWarnings.forEach(function(fiber) { - _uniqueNames2.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); + flushPassiveEffects(); + flushSync(function() { + scheduleFibersWithFamiliesRecursively( + root.current, + _updatedFamilies, + _staleFamilies + ); + }); + } +}; + +var scheduleRoot = function(root, element) { + { + if (root.context !== emptyContextObject) { + // Super edge case: root has a legacy _renderSubtree context + // but we don't know the parentComponent so we can't pass it. + // Just ignore. We'll delete this with _renderSubtree code path later. + return; + } + flushPassiveEffects(); + updateContainerAtExpirationTime(element, root, null, Sync, null); + } +}; - var _sortedNames2 = setToSortedString(_uniqueNames2); +function scheduleFibersWithFamiliesRecursively( + fiber, + updatedFamilies, + staleFamilies +) { + { + var alternate = fiber.alternate, + child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; - lowPriorityWarning$1( - false, - "componentWillUpdate is deprecated and will be removed in the next major version. " + - "Use componentDidUpdate instead. As a temporary workaround, " + - "you can rename to UNSAFE_componentWillUpdate." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - _sortedNames2 - ); + var candidateType = null; + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + default: + break; + } - pendingComponentWillUpdateWarnings = []; + if (resolveFamily === null) { + throw new Error("Expected resolveFamily to be set during hot reload."); } - }; - ReactStrictModeWarnings.recordDeprecationWarnings = function( - fiber, - instance - ) { - // Dedup strategy: Warn once per component. - if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) { - return; + var needsRender = false; + var needsRemount = false; + if (candidateType !== null) { + var family = resolveFamily(candidateType); + if (family !== undefined) { + if (staleFamilies.has(family)) { + needsRemount = true; + } else if (updatedFamilies.has(family)) { + needsRender = true; + } + } + } + if (failedBoundaries !== null) { + if ( + failedBoundaries.has(fiber) || + (alternate !== null && failedBoundaries.has(alternate)) + ) { + needsRemount = true; + } } - // Don't warn about react-lifecycles-compat polyfilled components. - if ( - typeof instance.componentWillMount === "function" && - instance.componentWillMount.__suppressDeprecationWarning !== true - ) { - pendingComponentWillMountWarnings.push(fiber); + if (needsRemount) { + fiber._debugNeedsRemount = true; } - if ( - typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== true - ) { - pendingComponentWillReceivePropsWarnings.push(fiber); + if (needsRemount || needsRender) { + scheduleWork(fiber, Sync); } - if ( - typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true - ) { - pendingComponentWillUpdateWarnings.push(fiber); + if (child !== null && !needsRemount) { + scheduleFibersWithFamiliesRecursively( + child, + updatedFamilies, + staleFamilies + ); } - }; - - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( - fiber, - instance - ) { - var strictRoot = findStrictRoot(fiber); - if (strictRoot === null) { - warningWithoutStack$1( - false, - "Expected to find a StrictMode component in a strict mode tree. " + - "This error is likely caused by a bug in React. Please file an issue." + if (sibling !== null) { + scheduleFibersWithFamiliesRecursively( + sibling, + updatedFamilies, + staleFamilies ); - return; } + } +} - // Dedup strategy: Warn once per component. - // This is difficult to track any other way since component names - // are often vague and are likely to collide between 3rd party libraries. - // An expand property is probably okay to use here since it's DEV-only, - // and will only be set in the event of serious warnings. - if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { - return; - } +var findHostInstancesForRefresh = function(root, families) { + { + var hostInstances = new Set(); + var types = new Set( + families.map(function(family) { + return family.current; + }) + ); + findHostInstancesForMatchingFibersRecursively( + root.current, + types, + hostInstances + ); + return hostInstances; + } +}; - var warningsForRoot = void 0; - if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) { - warningsForRoot = { - UNSAFE_componentWillMount: [], - UNSAFE_componentWillReceiveProps: [], - UNSAFE_componentWillUpdate: [] - }; +function findHostInstancesForMatchingFibersRecursively( + fiber, + types, + hostInstances +) { + { + var child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; - pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot); - } else { - warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot); + var candidateType = null; + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + default: + break; } - var unsafeLifecycles = []; - if ( - (typeof instance.componentWillMount === "function" && - instance.componentWillMount.__suppressDeprecationWarning !== true) || - typeof instance.UNSAFE_componentWillMount === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillMount"); - } - if ( - (typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== - true) || - typeof instance.UNSAFE_componentWillReceiveProps === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillReceiveProps"); - } - if ( - (typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true) || - typeof instance.UNSAFE_componentWillUpdate === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillUpdate"); + var didMatch = false; + if (candidateType !== null) { + if (types.has(candidateType)) { + didMatch = true; + } } - if (unsafeLifecycles.length > 0) { - unsafeLifecycles.forEach(function(lifecycle) { - warningsForRoot[lifecycle].push(fiber); - }); + if (didMatch) { + // We have a match. This only drills down to the closest host components. + // There's no need to search deeper because for the purpose of giving + // visual feedback, "flashing" outermost parent rectangles is sufficient. + findHostInstancesForFiberShallowly(fiber, hostInstances); + } else { + // If there's no match, maybe there will be one further down in the child tree. + if (child !== null) { + findHostInstancesForMatchingFibersRecursively( + child, + types, + hostInstances + ); + } } - }; - ReactStrictModeWarnings.recordLegacyContextWarning = function( - fiber, - instance - ) { - var strictRoot = findStrictRoot(fiber); - if (strictRoot === null) { - warningWithoutStack$1( - false, - "Expected to find a StrictMode component in a strict mode tree. " + - "This error is likely caused by a bug in React. Please file an issue." + if (sibling !== null) { + findHostInstancesForMatchingFibersRecursively( + sibling, + types, + hostInstances ); - return; } + } +} - // Dedup strategy: Warn once per component. - if (didWarnAboutLegacyContext.has(fiber.type)) { +function findHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var foundHostInstances = findChildHostInstancesForFiberShallowly( + fiber, + hostInstances + ); + if (foundHostInstances) { return; } + // If we didn't find any host children, fallback to closest host parent. + var node = fiber; + while (true) { + switch (node.tag) { + case HostComponent: + hostInstances.add(node.stateNode); + return; + case HostPortal: + hostInstances.add(node.stateNode.containerInfo); + return; + case HostRoot: + hostInstances.add(node.stateNode.containerInfo); + return; + } + if (node.return === null) { + throw new Error("Expected to reach root first."); + } + node = node.return; + } + } +} - var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); - - if ( - fiber.type.contextTypes != null || - fiber.type.childContextTypes != null || - (instance !== null && typeof instance.getChildContext === "function") - ) { - if (warningsForRoot === undefined) { - warningsForRoot = []; - pendingLegacyContextWarning.set(strictRoot, warningsForRoot); +function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var node = fiber; + var foundHostInstances = false; + while (true) { + if (node.tag === HostComponent) { + // We got a match. + foundHostInstances = true; + hostInstances.add(node.stateNode); + // There may still be more, so keep searching. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - warningsForRoot.push(fiber); + if (node === fiber) { + return foundHostInstances; + } + while (node.sibling === null) { + if (node.return === null || node.return === fiber) { + return foundHostInstances; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; } - }; - - ReactStrictModeWarnings.flushLegacyContextWarning = function() { - pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { - var uniqueNames = new Set(); - fiberArray.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutLegacyContext.add(fiber.type); - }); - - var sortedNames = setToSortedString(uniqueNames); - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - - warningWithoutStack$1( - false, - "Legacy context API has been detected within a strict-mode tree: %s" + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-strict-mode-warnings", - strictRootComponentStack, - sortedNames - ); - }); - }; + } + return false; } function resolveDefaultProps(Component, baseProps) { @@ -5972,7 +7178,7 @@ var lastContextWithAllBitsObserved = null; var isDisallowedContextReadInDEV = false; -function resetContextDependences() { +function resetContextDependencies() { // This is called right before React yields execution, to ensure `readContext` // cannot be called outside the render phase. currentlyRenderingFiber = null; @@ -6117,11 +7323,11 @@ function propagateContextChange( var nextFiber = void 0; // Visit this fiber. - var list = fiber.contextDependencies; + var list = fiber.dependencies; if (list !== null) { nextFiber = fiber.child; - var dependency = list.first; + var dependency = list.firstContext; while (dependency !== null) { // Check if the context matches. if ( @@ -6132,7 +7338,7 @@ function propagateContextChange( if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate(renderExpirationTime); + var update = createUpdate(renderExpirationTime, null); 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 @@ -6228,17 +7434,18 @@ function prepareToReadContext(workInProgress, renderExpirationTime) { lastContextDependency = null; lastContextWithAllBitsObserved = null; - var currentDependencies = workInProgress.contextDependencies; - if ( - currentDependencies !== null && - currentDependencies.expirationTime >= renderExpirationTime - ) { - // Context list has a pending update. Mark that this fiber performed work. - markWorkInProgressReceivedUpdate(); + var dependencies = workInProgress.dependencies; + if (dependencies !== null) { + var firstContext = dependencies.firstContext; + if (firstContext !== null) { + if (dependencies.expirationTime >= renderExpirationTime) { + // Context list has a pending update. Mark that this fiber performed work. + markWorkInProgressReceivedUpdate(); + } + // Reset the work-in-progress list + dependencies.firstContext = null; + } } - - // Reset the work-in-progress list - workInProgress.contextDependencies = null; } function readContext(context, observedBits) { @@ -6283,16 +7490,20 @@ function readContext(context, observedBits) { (function() { if (!(currentlyRenderingFiber !== null)) { throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); } })(); // This is the first dependency for this component. Create a new list. lastContextDependency = contextItem; - currentlyRenderingFiber.contextDependencies = { - first: contextItem, - expirationTime: NoWork + currentlyRenderingFiber.dependencies = { + expirationTime: NoWork, + firstContext: contextItem, + listeners: null, + responders: null }; } else { // Append a new context item. @@ -6432,9 +7643,10 @@ function cloneUpdateQueue(currentQueue) { return queue; } -function createUpdate(expirationTime) { - return { +function createUpdate(expirationTime, suspenseConfig) { + var update = { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: UpdateState, payload: null, @@ -6443,6 +7655,10 @@ function createUpdate(expirationTime) { next: null, nextEffect: null }; + { + update.priority = getCurrentPriorityLevel(); + } + return update; } function appendUpdateToQueue(queue, update) { @@ -6695,7 +7911,7 @@ function processUpdateQueue( // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTime(updateExpirationTime); + markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. resultState = getStateFromUpdate( @@ -6809,8 +8025,10 @@ function callCallback(callback, context) { (function() { if (!(typeof callback === "function")) { throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ) ); } })(); @@ -6864,6 +8082,12 @@ function commitUpdateEffects(effect, instance) { } } +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; + +function requestCurrentSuspenseConfig() { + return ReactCurrentBatchConfig.suspense; +} + var fakeInternalInstance = {}; var isArray$1 = Array.isArray; @@ -6937,7 +8161,9 @@ var didWarnAboutInvalidateContextType = void 0; (function() { { throw ReactError( - "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + Error( + "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + ) ); } })(); @@ -6990,9 +8216,14 @@ var classComponentUpdater = { enqueueSetState: function(inst, payload, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.payload = payload; if (callback !== undefined && callback !== null) { { @@ -7001,16 +8232,23 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.tag = ReplaceState; update.payload = payload; @@ -7021,16 +8259,23 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.tag = ForceUpdate; if (callback !== undefined && callback !== null) { @@ -7040,7 +8285,9 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); } @@ -7623,11 +8870,6 @@ function mountClassInstance( } if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( - workInProgress, - instance - ); - ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -7635,7 +8877,7 @@ function mountClassInstance( } if (warnAboutDeprecatedLifecycles) { - ReactStrictModeWarnings.recordDeprecationWarnings( + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance ); @@ -8043,7 +9285,9 @@ var warnForMissingKey = function(child) {}; (function() { if (!(typeof child._store === "object")) { throw ReactError( - "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." + Error( + "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8105,7 +9349,9 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!(ownerFiber.tag === ClassComponent)) { throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); } })(); @@ -8114,9 +9360,11 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!inst) { throw ReactError( - "Missing owner for string ref " + - mixedRef + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + mixedRef + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8148,16 +9396,20 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!(typeof mixedRef === "string")) { throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); } })(); (function() { if (!element._owner) { throw ReactError( - "Element ref was specified as a string (" + - mixedRef + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + mixedRef + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } })(); @@ -8178,12 +9430,14 @@ function throwOnInvalidObjectType(returnFiber, newChild) { (function() { { throw ReactError( - "Objects are not valid as a React child (found: " + - (Object.prototype.toString.call(newChild) === "[object Object]" - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + - addendum + Error( + "Objects are not valid as a React child (found: " + + (Object.prototype.toString.call(newChild) === "[object Object]" + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + + addendum + ) ); } })(); @@ -8853,7 +10107,9 @@ function ChildReconciler(shouldTrackSideEffects) { (function() { if (!(typeof iteratorFn === "function")) { throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8908,7 +10164,7 @@ function ChildReconciler(shouldTrackSideEffects) { var newChildren = iteratorFn.call(newChildrenIterable); (function() { if (!(newChildren != null)) { - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); } })(); @@ -9286,8 +10542,10 @@ function ChildReconciler(shouldTrackSideEffects) { (function() { { throw ReactError( - (Component.displayName || Component.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (Component.displayName || Component.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) ); } })(); @@ -9308,7 +10566,7 @@ var mountChildFibers = ChildReconciler(false); function cloneChildFibers(current$$1, workInProgress) { (function() { if (!(current$$1 === null || workInProgress.child === current$$1.child)) { - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); } })(); @@ -9337,6 +10595,15 @@ function cloneChildFibers(current$$1, workInProgress) { newChild.sibling = null; } +// Reset a workInProgress child set to prepare it for a second pass. +function resetChildFibers(workInProgress, renderExpirationTime) { + var child = workInProgress.child; + while (child !== null) { + resetWorkInProgress(child, renderExpirationTime); + child = child.sibling; + } +} + var NO_CONTEXT = {}; var contextStackCursor$1 = createCursor(NO_CONTEXT); @@ -9347,7 +10614,9 @@ function requiredContext(c) { (function() { if (!(c !== NO_CONTEXT)) { throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -9406,46 +10675,188 @@ function pushHostContext(fiber) { push(contextStackCursor$1, nextContext, fiber); } -function pushHostContextForEventComponent(fiber) { - var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContextForEventComponent(context); - - // Don't push this Fiber's context unless it's unique. - if (context === nextContext) { +function popHostContext(fiber) { + // Do not pop unless this Fiber provided the current context. + // pushHostContext() only pushes Fibers that provide unique contexts. + if (contextFiberStackCursor.current !== fiber) { return; } - // Track the context and the Fiber that provided it. - // This enables us to pop only Fibers that provide unique contexts. - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, nextContext, fiber); + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); } -function pushHostContextForEventTarget(fiber) { - var context = requiredContext(contextStackCursor$1.current); - var eventTargetType = fiber.type.type; - var nextContext = getChildHostContextForEventTarget(context, eventTargetType); +var DefaultSuspenseContext = 0; - // Don't push this Fiber's context unless it's unique. - if (context === nextContext) { - return; +// The Suspense Context is split into two parts. The lower bits is +// inherited deeply down the subtree. The upper bits only affect +// this immediate suspense boundary and gets reset each new +// boundary or suspense list. +var SubtreeSuspenseContextMask = 1; + +// Subtree Flags: + +// InvisibleParentSuspenseContext indicates that one of our parent Suspense +// boundaries is not currently showing visible main content. +// Either because it is already showing a fallback or is not mounted at all. +// We can use this to determine if it is desirable to trigger a fallback at +// the parent. If not, then we might need to trigger undesirable boundaries +// and/or suspend the commit to avoid hiding the parent content. +var InvisibleParentSuspenseContext = 1; + +// Shallow Flags: + +// ForceSuspenseFallback can be used by SuspenseList to force newly added +// items into their fallback state during one of the render passes. +var ForceSuspenseFallback = 2; + +var suspenseStackCursor = createCursor(DefaultSuspenseContext); + +function hasSuspenseContext(parentContext, flag) { + return (parentContext & flag) !== 0; +} + +function setDefaultShallowSuspenseContext(parentContext) { + return parentContext & SubtreeSuspenseContextMask; +} + +function setShallowSuspenseContext(parentContext, shallowContext) { + return (parentContext & SubtreeSuspenseContextMask) | shallowContext; +} + +function addSubtreeSuspenseContext(parentContext, subtreeContext) { + return parentContext | subtreeContext; +} + +function pushSuspenseContext(fiber, newContext) { + push(suspenseStackCursor, newContext, fiber); +} + +function popSuspenseContext(fiber) { + pop(suspenseStackCursor, fiber); +} + +// TODO: This is now an empty object. Should we switch this to a boolean? +// Alternatively we can make this use an effect tag similar to SuspenseList. + +function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { + // If it was the primary children that just suspended, capture and render the + var nextState = workInProgress.memoizedState; + if (nextState !== null) { + return false; + } + var props = workInProgress.memoizedProps; + // In order to capture, the Suspense component must have a fallback prop. + if (props.fallback === undefined) { + return false; + } + // Regular boundaries always capture. + if (props.unstable_avoidThisFallback !== true) { + return true; } + // If it's a boundary we should avoid, then we prefer to bubble up to the + // parent boundary if it is currently invisible. + if (hasInvisibleParent) { + return false; + } + // If the parent is not able to handle it, we must handle it. + return true; +} - // Track the context and the Fiber that provided it. - // This enables us to pop only Fibers that provide unique contexts. - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, nextContext, fiber); +function findFirstSuspended(row) { + var node = row; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + return node; + } + } else if ( + node.tag === SuspenseListComponent && + // revealOrder undefined can't be trusted because it don't + // keep track of whether it suspended or not. + node.memoizedProps.revealOrder !== undefined + ) { + var didSuspend = (node.effectTag & DidCapture) !== NoEffect; + if (didSuspend) { + return node; + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) { + return null; + } + while (node.sibling === null) { + if (node.return === null || node.return === row) { + return null; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; } -function popHostContext(fiber) { - // Do not pop unless this Fiber provided the current context. - // pushHostContext() only pushes Fibers that provide unique contexts. - if (contextFiberStackCursor.current !== fiber) { - return; +var currentlyRenderingFiber$2 = null; +var currentListenerHookIndex = 0; + +function prepareToReadListenerHooks(workInProgress) { + currentlyRenderingFiber$2 = workInProgress; + currentListenerHookIndex = 0; +} + +function getListenerHooks() { + var listeners = void 0; + var dependencies = currentlyRenderingFiber$2.dependencies; + if (dependencies === null) { + dependencies = currentlyRenderingFiber$2.dependencies = { + expirationTime: NoWork, + firstContext: null, + listeners: [], + responders: null + }; + } + listeners = dependencies.listeners; + if (listeners === null) { + dependencies.listeners = listeners = []; + } + return listeners; +} + +function updateListenerHook(responder, props) { + var listeners = getListenerHooks(); + if (listeners.length === currentListenerHookIndex) { + listeners.push({ + responder: responder, + props: props + }); + currentListenerHookIndex++; + } else { + var currentListenerHook = listeners[currentListenerHookIndex++]; + currentListenerHook.responder = responder; + currentListenerHook.props = props; } +} - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); +function createResponderInstance( + responder, + responderProps, + responderState, + target, + fiber +) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState, + target: target + }; } var NoEffect$1 = /* */ 0; @@ -9605,7 +11016,9 @@ function throwInvalidHookError() { (function() { { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } })(); @@ -9786,7 +11199,9 @@ function renderWithHooks( (function() { if (!!didRenderTooFewHooks) { throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); } })(); @@ -9874,7 +11289,7 @@ function updateWorkInProgressHook() { (function() { if (!(nextCurrentHook !== null)) { throw ReactError( - "Rendered more hooks than during the previous render." + Error("Rendered more hooks than during the previous render.") ); } })(); @@ -9942,7 +11357,9 @@ function updateReducer(reducer, initialArg, init) { (function() { if (!(queue !== null)) { throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); } })(); @@ -9975,7 +11392,7 @@ function updateReducer(reducer, initialArg, init) { } hook.memoizedState = newState; - // Don't persist the state accumlated from the render phase updates to + // Don't persist the state accumulated from the render phase updates to // the base state unless the queue is empty. // TODO: Not sure if this is the desired semantics, but it's what we // do for gDSFP. I can't remember why. @@ -10041,7 +11458,10 @@ function updateReducer(reducer, initialArg, init) { // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTime(updateExpirationTime); + markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ); // Process this update. if (_update.eagerReducer === reducer) { @@ -10174,6 +11594,12 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { } function mountEffect(create, deps) { + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } return mountEffectImpl( Update | Passive, UnmountPassive | MountPassive, @@ -10183,6 +11609,12 @@ function mountEffect(create, deps) { } function updateEffect(create, deps) { + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } return updateEffectImpl( Update | Passive, UnmountPassive | MountPassive, @@ -10336,7 +11768,9 @@ function dispatchAction(fiber, queue, action) { (function() { if (!(numberOfReRenders < RE_RENDER_LIMIT)) { throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); } })(); @@ -10363,11 +11797,15 @@ function dispatchAction(fiber, queue, action) { didScheduleRenderPhaseUpdate = true; var update = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, next: null }; + { + update.priority = getCurrentPriorityLevel(); + } if (renderPhaseUpdates === null) { renderPhaseUpdates = new Map(); } @@ -10383,19 +11821,31 @@ function dispatchAction(fiber, queue, action) { lastRenderPhaseUpdate.next = update; } } else { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } var currentTime = requestCurrentTime(); - var _expirationTime = computeExpirationForFiber(currentTime, fiber); + var _suspenseConfig = requestCurrentSuspenseConfig(); + var _expirationTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); var _update2 = { expirationTime: _expirationTime, + suspenseConfig: _suspenseConfig, action: action, eagerReducer: null, eagerState: null, next: null }; + { + _update2.priority = getCurrentPriorityLevel(); + } + // Append the update to the end of the list. var _last = queue.last; if (_last === null) { @@ -10451,10 +11901,9 @@ function dispatchAction(fiber, queue, action) { } } { - // jest isn't a 'global', it's just exposed to tests via a wrapped function - // further, this isn't a test file, so flow doesn't recognize the symbol. So... - // $FlowExpectedError - because requirements don't give a damn about your type sigs. + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(fiber); warnIfNotCurrentlyActingUpdatesInDev(fiber); } } @@ -10474,7 +11923,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }; var HooksDispatcherOnMountInDEV = null; @@ -10580,6 +12030,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + mountHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10654,6 +12109,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + updateHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10728,6 +12188,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); return updateDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + updateHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10813,6 +12278,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); mountHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + warnInvalidHookAccess(); + mountHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10898,6 +12369,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); updateHookTypesDev(); return updateDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + warnInvalidHookAccess(); + updateHookTypesDev(); + updateListenerHook(responder, props); } }; } @@ -11167,7 +12644,9 @@ function prepareToHydrateHostInstance( (function() { { throw ReactError( - "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11197,7 +12676,9 @@ function prepareToHydrateHostTextInstance(fiber) { (function() { { throw ReactError( - "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11247,7 +12728,9 @@ function skipPastDehydratedSuspenseInstance(fiber) { (function() { { throw ReactError( - "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11256,7 +12739,9 @@ function skipPastDehydratedSuspenseInstance(fiber) { (function() { if (!suspenseInstance) { throw ReactError( - "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11344,6 +12829,9 @@ var didWarnAboutGetDerivedStateOnFunctionComponent = void 0; var didWarnAboutFunctionRefs = void 0; var didWarnAboutReassigningProps = void 0; var didWarnAboutMaxDuration = void 0; +var didWarnAboutRevealOrder = void 0; +var didWarnAboutTailOptions = void 0; +var didWarnAboutDefaultPropsOnFunctionComponent = void 0; { didWarnAboutBadClass = {}; @@ -11353,6 +12841,9 @@ var didWarnAboutMaxDuration = void 0; didWarnAboutFunctionRefs = {}; didWarnAboutReassigningProps = false; didWarnAboutMaxDuration = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; } function reconcileChildren( @@ -11454,6 +12945,9 @@ function updateForwardRef( // The rest is a fork of updateFunctionComponent var nextChildren = void 0; prepareToReadContext(workInProgress, renderExpirationTime); + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } { ReactCurrentOwner$3.current = workInProgress; setCurrentPhase("render"); @@ -11472,6 +12966,9 @@ function updateForwardRef( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } nextChildren = renderWithHooks( current$$1, workInProgress, @@ -11756,6 +13253,9 @@ function updateFunctionComponent( var nextChildren = void 0; prepareToReadContext(workInProgress, renderExpirationTime); + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } { ReactCurrentOwner$3.current = workInProgress; setCurrentPhase("render"); @@ -11774,6 +13274,9 @@ function updateFunctionComponent( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } nextChildren = renderWithHooks( current$$1, workInProgress, @@ -12027,7 +13530,9 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { (function() { if (!(updateQueue !== null)) { throw ReactError( - "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." + 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." + ) ); } })(); @@ -12125,10 +13630,13 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { // Check the host config to see if the children are offscreen/hidden. if ( - renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps) ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. workInProgress.expirationTime = workInProgress.childExpirationTime = Never; return null; @@ -12270,10 +13778,12 @@ function mountLazyComponent( (function() { { throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ) ); } })(); @@ -12362,7 +13872,9 @@ function mountIndeterminateComponent( var context = getMaskedContext(workInProgress, unmaskedContext); prepareToReadContext(workInProgress, renderExpirationTime); - + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } var value = void 0; { @@ -12476,6 +13988,9 @@ function mountIndeterminateComponent( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } value = renderWithHooks( null, workInProgress, @@ -12529,16 +14044,33 @@ function validateFunctionComponentInDev(workInProgress, Component) { } } - if (typeof Component.getDerivedStateFromProps === "function") { + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { var componentName = getComponentName(Component) || "Unknown"; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) { + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { warningWithoutStack$1( false, - "%s: Function components do not support getDerivedStateFromProps.", + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", componentName ); - didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true; + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } + + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + warningWithoutStack$1( + false, + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; } } @@ -12546,19 +14078,31 @@ function validateFunctionComponentInDev(workInProgress, Component) { typeof Component.contextType === "object" && Component.contextType !== null ) { - var _componentName2 = getComponentName(Component) || "Unknown"; + var _componentName3 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName2]) { + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { warningWithoutStack$1( false, "%s: Function components do not support contextType.", - _componentName2 + _componentName3 ); - didWarnAboutContextTypeOnFunctionComponent[_componentName2] = true; + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; } } } +// TODO: This is now an empty object. Should we just make it a boolean? +var SUSPENDED_MARKER = {}; + +function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { + // If the context is telling us that we should show a fallback, and we're not + // already showing content, then we should show the fallback instead. + return ( + hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && + (current$$1 === null || current$$1.memoizedState !== null) + ); +} + function updateSuspenseComponent( current$$1, workInProgress, @@ -12567,32 +14111,51 @@ function updateSuspenseComponent( var mode = workInProgress.mode; var nextProps = workInProgress.pendingProps; + // This is used by DevTools to force a boundary to suspend. { if (shouldSuspend(workInProgress)) { workInProgress.effectTag |= DidCapture; } } - // We should attempt to render the primary children unless this boundary - // already suspended during this render (`alreadyCaptured` is true). - var nextState = workInProgress.memoizedState; + var suspenseContext = suspenseStackCursor.current; - var nextDidTimeout = void 0; - if ((workInProgress.effectTag & DidCapture) === NoEffect) { - // This is the first attempt. - nextState = null; - nextDidTimeout = false; - } else { + var nextState = null; + var nextDidTimeout = false; + + if ( + (workInProgress.effectTag & DidCapture) !== NoEffect || + shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) + ) { // Something in this boundary's subtree already suspended. Switch to // rendering the fallback children. - nextState = { - fallbackExpirationTime: - nextState !== null ? nextState.fallbackExpirationTime : NoWork - }; + nextState = SUSPENDED_MARKER; nextDidTimeout = true; workInProgress.effectTag &= ~DidCapture; + } else { + // Attempting the main content + if (current$$1 === null || current$$1.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); + { if ("maxDuration" in nextProps) { if (!didWarnAboutMaxDuration) { @@ -12645,6 +14208,7 @@ function updateSuspenseComponent( tryToClaimNextHydratableInstance(workInProgress); // This could've changed the tag if this was a dehydrated suspense component. if (workInProgress.tag === DehydratedSuspenseComponent) { + popSuspenseContext(workInProgress); return updateDehydratedSuspenseComponent( null, workInProgress, @@ -12665,15 +14229,21 @@ function updateSuspenseComponent( NoWork, null ); + primaryChildFragment.return = workInProgress; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var progressedState = workInProgress.memoizedState; var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child; primaryChildFragment.child = progressedPrimaryChild; + var progressedChild = progressedPrimaryChild; + while (progressedChild !== null) { + progressedChild.return = primaryChildFragment; + progressedChild = progressedChild.sibling; + } } var fallbackChildFragment = createFiberFromFragment( @@ -12682,12 +14252,12 @@ function updateSuspenseComponent( renderExpirationTime, null ); + fallbackChildFragment.return = workInProgress; primaryChildFragment.sibling = fallbackChildFragment; child = primaryChildFragment; // Skip the primary children, and continue working on the // fallback children. next = fallbackChildFragment; - child.return = next.return = workInProgress; } else { // Mount the primary children without an intermediate fragment fiber. var nextPrimaryChildren = nextProps.children; @@ -12716,9 +14286,10 @@ function updateSuspenseComponent( currentPrimaryChildFragment.pendingProps, NoWork ); + _primaryChildFragment.return = workInProgress; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var _progressedState = workInProgress.memoizedState; var _progressedPrimaryChild = _progressedState !== null @@ -12726,6 +14297,11 @@ function updateSuspenseComponent( : workInProgress.child; if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { _primaryChildFragment.child = _progressedPrimaryChild; + var _progressedChild = _progressedPrimaryChild; + while (_progressedChild !== null) { + _progressedChild.return = _primaryChildFragment; + _progressedChild = _progressedChild.sibling; + } } } @@ -12744,17 +14320,18 @@ function updateSuspenseComponent( // Clone the fallback child fragment, too. These we'll continue // working on. - var _fallbackChildFragment = (_primaryChildFragment.sibling = createWorkInProgress( + var _fallbackChildFragment = createWorkInProgress( currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime - )); + ); + _fallbackChildFragment.return = workInProgress; + _primaryChildFragment.sibling = _fallbackChildFragment; child = _primaryChildFragment; _primaryChildFragment.childExpirationTime = NoWork; // Skip the primary children, and continue working on the // fallback children. next = _fallbackChildFragment; - child.return = next.return = workInProgress; } else { // No longer suspended. Switch back to showing the primary children, // and remove the intermediate fragment fiber. @@ -12792,21 +14369,30 @@ function updateSuspenseComponent( NoWork, null ); + _primaryChildFragment2.return = workInProgress; _primaryChildFragment2.child = _currentPrimaryChild; + if (_currentPrimaryChild !== null) { + _currentPrimaryChild.return = _primaryChildFragment2; + } // Even though we're creating a new fiber, there are no new children, // because we're reusing an already mounted tree. So we don't need to // schedule a placement. // primaryChildFragment.effectTag |= Placement; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var _progressedState2 = workInProgress.memoizedState; var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child; _primaryChildFragment2.child = _progressedPrimaryChild2; + var _progressedChild2 = _progressedPrimaryChild2; + while (_progressedChild2 !== null) { + _progressedChild2.return = _primaryChildFragment2; + _progressedChild2 = _progressedChild2.sibling; + } } // Because primaryChildFragment is a new fiber that we're inserting as the @@ -12823,19 +14409,20 @@ function updateSuspenseComponent( } // Create a fragment from the fallback children, too. - var _fallbackChildFragment2 = (_primaryChildFragment2.sibling = createFiberFromFragment( + var _fallbackChildFragment2 = createFiberFromFragment( _nextFallbackChildren2, mode, renderExpirationTime, null - )); + ); + _fallbackChildFragment2.return = workInProgress; + _primaryChildFragment2.sibling = _fallbackChildFragment2; _fallbackChildFragment2.effectTag |= Placement; child = _primaryChildFragment2; _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the // fallback children. next = _fallbackChildFragment2; - child.return = next.return = workInProgress; } else { // Still haven't timed out. Continue rendering the children, like we // normally do. @@ -12870,7 +14457,9 @@ function retrySuspenseComponentWithoutHydrating( (function() { if (!(returnFiber !== null)) { throw ReactError( - "Suspense boundaries are never on the root. This is probably a bug in React." + Error( + "Suspense boundaries are never on the root. This is probably a bug in React." + ) ); } })(); @@ -12884,6 +14473,8 @@ function retrySuspenseComponentWithoutHydrating( current$$1.nextEffect = null; current$$1.effectTag = Deletion; + popSuspenseContext(workInProgress); + // Upgrade this work in progress to a real Suspense component. workInProgress.tag = SuspenseComponent; workInProgress.stateNode = null; @@ -12899,6 +14490,10 @@ function updateDehydratedSuspenseComponent( workInProgress, renderExpirationTime ) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); var suspenseInstance = workInProgress.stateNode; if (current$$1 === null) { // During the first pass, we'll bail out and not drill into the children. @@ -12991,6 +14586,382 @@ function updateDehydratedSuspenseComponent( } } +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderExpirationTime +) { + // 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; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + if (node.expirationTime < renderExpirationTime) { + node.expirationTime = renderExpirationTime; + } + var alternate = node.alternate; + if ( + alternate !== null && + alternate.expirationTime < renderExpirationTime + ) { + alternate.expirationTime = renderExpirationTime; + } + scheduleWorkOnParentPath(node.return, renderExpirationTime); + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) { + return; + } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} + +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; + } + row = row.sibling; + } + return lastContentRow; +} + +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + case "forward": + case "backward": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + default: + warning$1( + false, + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { + warning$1( + false, + "%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; + warning$1( + false, + '"%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; + warning$1( + false, + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); + } + } + } +} + +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + warning$1( + false, + "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; + } + } + 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 { + var iteratorFn = getIteratorFn(children); + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + _i++; + } + } + } else { + warning$1( + false, + '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 +) { + var renderState = workInProgress.memoizedState; + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailExpiration = 0; + 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. +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + 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$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + + var suspenseContext = suspenseStackCursor.current; + + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.effectTag |= DidCapture; + } else { + var didSuspendBefore = + current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; + 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, + renderExpirationTime + ); + } + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } + pushSuspenseContext(workInProgress, suspenseContext); + + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched 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 = void 0; + 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; + } + case "together": { + initSuspenseListRenderState( + workInProgress, + 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 workInProgress.child; +} + function updatePortalComponent( current$$1, workInProgress, @@ -13154,11 +15125,15 @@ function updateContextConsumer( return workInProgress.child; } -function updateEventComponent$1( +function updateFundamentalComponent$1( current$$1, workInProgress, renderExpirationTime ) { + var fundamentalImpl = workInProgress.type.impl; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; @@ -13168,38 +15143,6 @@ function updateEventComponent$1( nextChildren, renderExpirationTime ); - pushHostContextForEventComponent(workInProgress); - return workInProgress.child; -} - -function updateEventTarget(current$$1, workInProgress, renderExpirationTime) { - var type = workInProgress.type.type; - var nextProps = workInProgress.pendingProps; - var eventTargetChild = getEventTargetChildElement(type, nextProps); - - { - !(nextProps.children == null) - ? warning$1(false, "Event targets should not have children.") - : void 0; - } - if (eventTargetChild !== null) { - var child = (workInProgress.child = createFiberFromTypeAndProps( - eventTargetChild.type, - null, - eventTargetChild.props, - null, - workInProgress.mode, - renderExpirationTime - )); - child.return = workInProgress; - - if (current$$1 === null || current$$1.child === null) { - child.effectTag = Placement; - } - } else { - reconcileChildren(current$$1, workInProgress, null, renderExpirationTime); - } - pushHostContextForEventTarget(workInProgress); return workInProgress.child; } @@ -13215,8 +15158,8 @@ function bailoutOnAlreadyFinishedWork( cancelWorkTimer(workInProgress); if (current$$1 !== null) { - // Reuse previous context list - workInProgress.contextDependencies = current$$1.contextDependencies; + // Reuse previous dependencies + workInProgress.dependencies = current$$1.dependencies; } if (enableProfilerTimer) { @@ -13339,6 +15282,18 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { break; case HostComponent: pushHostContext(workInProgress); + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(workInProgress.type, newProps) + ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + // Schedule this fiber to re-render at offscreen priority. Then bailout. + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } break; case ClassComponent: { var Component = workInProgress.type; @@ -13385,6 +15340,10 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ); } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient // priority. Bailout. var child = bailoutOnAlreadyFinishedWork( @@ -13400,11 +15359,20 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { return null; } } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } break; } case DehydratedSuspenseComponent: { if (enableSuspenseServerRenderer) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has // been unsuspended it has committed as a regular Suspense component. // If it needs to be retried, it should have work scheduled on it. @@ -13412,15 +15380,46 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } break; } - case EventComponent: - if (enableEventAPI) { - pushHostContextForEventComponent(workInProgress); + case SuspenseListComponent: { + var didSuspendBefore = + (current$$1.effectTag & DidCapture) !== NoEffect; + + var childExpirationTime = workInProgress.childExpirationTime; + if (childExpirationTime < renderExpirationTime) { + // 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. + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (didSuspendBefore) { + workInProgress.effectTag |= DidCapture; + } + return null; } - break; - case EventTarget: { - if (enableEventAPI) { - pushHostContextForEventTarget(workInProgress); + + if (didSuspendBefore) { + // 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$$1, + workInProgress, + renderExpirationTime + ); + } + + // 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; } + pushSuspenseContext(workInProgress, suspenseStackCursor.current); break; } } @@ -13605,19 +15604,16 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } break; } - case EventComponent: { - if (enableEventAPI) { - return updateEventComponent$1( - current$$1, - workInProgress, - renderExpirationTime - ); - } - break; + case SuspenseListComponent: { + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } - case EventTarget: { - if (enableEventAPI) { - return updateEventTarget( + case FundamentalComponent: { + if (enableFundamentalAPI) { + return updateFundamentalComponent$1( current$$1, workInProgress, renderExpirationTime @@ -13629,12 +15625,28 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { (function() { { throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); } +function createFundamentalStateInstance(currentFiber, props, impl, state) { + return { + currentFiber: currentFiber, + impl: impl, + instance: null, + prevProps: null, + props: props, + state: state + }; +} + +var emptyObject$1 = {}; +var isArray$2 = Array.isArray; + function markUpdate(workInProgress) { // Tag the fiber with an update effect. This turns a Placement into // a PlacementAndUpdate. @@ -13664,6 +15676,8 @@ if (supportsMutation) { while (node !== null) { if (node.tag === HostComponent || node.tag === HostText) { appendInitialChild(parent, node.stateNode); + } else if (node.tag === FundamentalComponent) { + appendInitialChild(parent, node.stateNode.instance); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -13768,6 +15782,15 @@ if (supportsMutation) { _instance = cloneHiddenTextInstance(_instance, text, node); } appendInitialChild(parent, _instance); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance2 = node.stateNode.instance; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props = node.memoizedProps; + var _type = node.type; + _instance2 = cloneHiddenInstance(_instance2, _type, _props, node); + } + appendInitialChild(parent, _instance2); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -13846,13 +15869,22 @@ if (supportsMutation) { } appendChildToContainerChildSet(containerChildSet, instance); } else if (node.tag === HostText) { - var _instance2 = node.stateNode; + var _instance3 = node.stateNode; if (needsVisibilityToggle && isHidden) { // This child is inside a timed out tree. Hide it. var text = node.memoizedProps; - _instance2 = cloneHiddenTextInstance(_instance2, text, node); + _instance3 = cloneHiddenTextInstance(_instance3, text, node); + } + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance4 = node.stateNode.instance; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props2 = node.memoizedProps; + var _type2 = node.type; + _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node); } - appendChildToContainerChildSet(containerChildSet, _instance2); + appendChildToContainerChildSet(containerChildSet, _instance4); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -14028,6 +16060,69 @@ if (supportsMutation) { }; } +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + tailNode = tailNode.sibling; + } + // Next we're simply going to delete all insertions after the + // last rendered item. + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } + break; + } + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } + _tailNode = _tailNode.sibling; + } + // Next we're simply going to delete all insertions after the + // last rendered item. + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + break; + } + } +} + function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; @@ -14078,6 +16173,20 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); + if (enableFlareAPI) { + var prevResponders = current.memoizedProps.responders; + var nextResponders = newProps.responders; + var instance = workInProgress.stateNode; + if (prevResponders !== nextResponders) { + updateEventResponders( + nextResponders, + instance, + rootContainerInstance, + workInProgress + ); + } + } + if (current.ref !== workInProgress.ref) { markRef$1(workInProgress); } @@ -14086,7 +16195,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { if (!(workInProgress.stateNode !== null)) { throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14115,7 +16226,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } else { - var instance = createInstance( + var _instance5 = createInstance( type, newProps, rootContainerInstance, @@ -14123,14 +16234,26 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress ); - appendAllChildren(instance, workInProgress, false, false); + appendAllChildren(_instance5, workInProgress, false, false); + + if (enableFlareAPI) { + var responders = newProps.responders; + if (responders != null) { + updateEventResponders( + responders, + _instance5, + rootContainerInstance, + workInProgress + ); + } + } // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. if ( finalizeInitialChildren( - instance, + _instance5, type, newProps, rootContainerInstance, @@ -14139,7 +16262,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { ) { markUpdate(workInProgress); } - workInProgress.stateNode = instance; + workInProgress.stateNode = _instance5; } if (workInProgress.ref !== null) { @@ -14161,7 +16284,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { if (!(workInProgress.stateNode !== null)) { throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14188,6 +16313,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { case ForwardRef: break; case SuspenseComponent: { + popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; if ((workInProgress.effectTag & DidCapture) !== NoEffect) { // Something suspended. Re-render with the fallback children. @@ -14208,15 +16334,8 @@ function completeWork(current, workInProgress, renderExpirationTime) { prevDidTimeout = prevState !== null; if (!nextDidTimeout && prevState !== null) { // We just switched from the fallback to the normal children. - - // Mark the event time of the switching from fallback to normal children, - // based on the start of when we first showed the fallback. This time - var fallbackExpirationTime = prevState.fallbackExpirationTime; - markRenderEventTime(fallbackExpirationTime); - // Delete the fallback. // TODO: Would it be better to store the fallback fragment on - // the stateNode during the begin phase? var currentFallbackChild = current.child.sibling; if (currentFallbackChild !== null) { // Deletions go at the beginning of the return fiber's effect list @@ -14234,13 +16353,37 @@ function completeWork(current, workInProgress, renderExpirationTime) { } if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in concurrent mode we can suspend, + // If this subtreee is running in batched 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 & ConcurrentMode) !== NoContext) { - renderDidSuspend(); + if ((workInProgress.mode & BatchedMode) !== 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(); + } } } @@ -14264,6 +16407,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.effectTag |= Update; } } + if ( + enableSuspenseCallback && + workInProgress.updateQueue !== null && + workInProgress.memoizedProps.suspenseCallback != null + ) { + // Always notify the callback + workInProgress.effectTag |= Update; + } break; } case Fragment: @@ -14295,15 +16446,21 @@ function completeWork(current, workInProgress, renderExpirationTime) { } case DehydratedSuspenseComponent: { if (enableSuspenseServerRenderer) { + popSuspenseContext(workInProgress); if (current === null) { var _wasHydrated2 = popHydrationState(workInProgress); (function() { if (!_wasHydrated2) { throw ReactError( - "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ) ); } })(); + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } skipPastDehydratedSuspenseInstance(workInProgress); } else if ((workInProgress.effectTag & DidCapture) === NoEffect) { // This boundary did not suspend so it's now hydrated. @@ -14318,55 +16475,239 @@ function completeWork(current, workInProgress, renderExpirationTime) { } break; } - case EventComponent: { - if (enableEventAPI) { - popHostContext(workInProgress); - var _rootContainerInstance2 = getRootHostContainer(); - var responder = workInProgress.type.responder; - var eventComponentInstance = workInProgress.stateNode; - - if (eventComponentInstance === null) { - var responderState = null; - if (responder.createInitialState !== undefined) { - responderState = responder.createInitialState(newProps); + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. We don't do anything + // in this mode. + break; + } + + var didSuspendAlready = + (workInProgress.effectTag & DidCapture) !== NoEffect; + + var renderedTail = renderState.rendering; + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.effectTag & DidCapture) === NoEffect); + if (!cannotBeSuspended) { + var row = workInProgress.child; + while (row !== null) { + var suspended = findFirstSuspended(row); + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.effectTag |= 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. + var newThennables = suspended.updateQueue; + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.effectTag |= 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. + workInProgress.firstEffect = workInProgress.lastEffect = null; + // Reset the child fibers to their original state. + resetChildFibers(workInProgress, renderExpirationTime); + + // Set up the Suspense Context to force suspense and immediately + // rerender the children. + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } + row = row.sibling; + } } - eventComponentInstance = workInProgress.stateNode = { - currentFiber: workInProgress, - props: newProps, - responder: responder, - rootEventTypes: null, - rootInstance: _rootContainerInstance2, - state: responderState - }; - markUpdate(workInProgress); } else { - // Update the props on the event component state node - eventComponentInstance.props = newProps; - // Update the root container, so we can properly unmount events at some point - eventComponentInstance.rootInstance = _rootContainerInstance2; - // Update the current fiber - eventComponentInstance.currentFiber = workInProgress; - updateEventComponent(eventComponentInstance); + cutOffTailIfNeeded(renderState, false); + } + // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + if (_suspended !== null) { + workInProgress.effectTag |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, true); + // This might have been modified. + if ( + renderState.tail === null && + renderState.tailMode === "hidden" + ) { + // We need to delete the row we just rendered. + // Ensure we transfer the update queue to the parent. + var _newThennables = _suspended.updateQueue; + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.effectTag |= Update; + } + // Reset the effect list to what it w as 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. + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } + // We're done. + return null; + } + } else if ( + now() > renderState.tailExpiration && + renderExpirationTime > Never + ) { + // 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.effectTag |= 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. If we can show + // them, then they really have the same priority as this render. + // So we'll pick it back up the very next render pass once we've had + // an opportunity to yield for paint. + + var nextPriority = renderExpirationTime - 1; + workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; + if (enableSchedulerTracing) { + markSpawnedWork(nextPriority); + } + } + } + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } + renderState.last = renderedTail; + } + } + + if (renderState.tail !== null) { + // We still have tail rows to render. + if (renderState.tailExpiration === 0) { + // Heuristic for how long we're willing to spend rendering rows + // until we just give up and show what we have so far. + var TAIL_EXPIRATION_TIMEOUT_MS = 500; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + } + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.lastEffect = workInProgress.lastEffect; + next.sibling = null; + + // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + var suspenseContext = suspenseStackCursor.current; + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } + pushSuspenseContext(workInProgress, suspenseContext); + // Do a pass over the next row. + return next; } break; } - case EventTarget: { - if (enableEventAPI) { - popHostContext(workInProgress); - var _type = workInProgress.type.type; - var _rootContainerInstance3 = getRootHostContainer(); - var shouldUpdate = handleEventTarget( - _type, - newProps, - _rootContainerInstance3, - workInProgress - ); - // Update the latest props on the stateNode. This is used - // during the event phase to find the most current props. - workInProgress.stateNode.props = newProps; - if (shouldUpdate) { - markUpdate(workInProgress); + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalImpl = workInProgress.type.impl; + var fundamentalInstance = workInProgress.stateNode; + + if (fundamentalInstance === null) { + var getInitialState = fundamentalImpl.getInitialState; + var fundamentalState = void 0; + if (getInitialState !== undefined) { + fundamentalState = getInitialState(newProps); + } + fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance( + workInProgress, + newProps, + fundamentalImpl, + fundamentalState || {} + ); + var _instance6 = getFundamentalComponentInstance(fundamentalInstance); + fundamentalInstance.instance = _instance6; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } + appendAllChildren(_instance6, workInProgress, false, false); + mountFundamentalComponent(fundamentalInstance); + } else { + // We fire update in commit phase + var prevProps = fundamentalInstance.props; + fundamentalInstance.prevProps = prevProps; + fundamentalInstance.props = newProps; + fundamentalInstance.currentFiber = workInProgress; + if (supportsPersistence) { + var _instance7 = cloneFundamentalInstance(fundamentalInstance); + fundamentalInstance.instance = _instance7; + appendAllChildren(_instance7, workInProgress, false, false); + } + var shouldUpdate = shouldUpdateFundamentalComponent( + fundamentalInstance + ); + if (shouldUpdate) { + markUpdate(workInProgress); + } } } break; @@ -14375,7 +16716,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { { throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14384,15 +16727,263 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } -function shouldCaptureSuspense(workInProgress) { - // In order to capture, the Suspense component must have a fallback prop. - if (workInProgress.memoizedProps.fallback === undefined) { - return false; +function mountEventResponder$1( + responder, + responderProps, + instance, + rootContainerInstance, + fiber, + respondersMap +) { + var responderState = emptyObject$1; + var getInitialState = responder.getInitialState; + if (getInitialState !== null) { + responderState = getInitialState(responderProps); + } + var responderInstance = createResponderInstance( + responder, + responderProps, + responderState, + instance, + fiber + ); + mountResponderInstance( + responder, + responderInstance, + responderProps, + responderState, + instance, + rootContainerInstance + ); + respondersMap.set(responder, responderInstance); +} + +function updateEventResponder( + responder, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance +) { + (function() { + if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) { + throw ReactError( + Error( + "An invalid value was used as an event responder. Expect one or many event responders created via React.unstable_createResponer()." + ) + ); + } + })(); + if (visistedResponders.has(responder)) { + // show warning + return; + } + visistedResponders.add(responder); + var responderInstance = respondersMap.get(responder); + + if (responderInstance === undefined) { + // Mount + mountEventResponder$1( + responder, + props, + instance, + rootContainerInstance, + fiber, + respondersMap + ); + } else { + // Update + responderInstance.props = props; + responderInstance.fiber = fiber; + } +} + +function updateEventResponders( + responders, + instance, + rootContainerInstance, + fiber +) { + var visistedResponders = new Set(); + var dependencies = fiber.dependencies; + if (responders != null) { + if (dependencies === null) { + dependencies = fiber.dependencies = { + expirationTime: NoWork, + firstContext: null, + listeners: null, + responders: new Map() + }; + } + var respondersMap = dependencies.responders; + if (respondersMap === null) { + respondersMap = new Map(); + } + if (isArray$2(responders)) { + for (var i = 0, length = responders.length; i < length; i++) { + var _responders$i = responders[i], + type = _responders$i.type, + props = _responders$i.props; + + updateEventResponder( + type, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance + ); + } + } else { + var type = responders.type, + props = responders.props; + + updateEventResponder( + type, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance + ); + } + } + if (dependencies !== null) { + var _respondersMap = dependencies.responders; + if (_respondersMap !== null) { + // Unmount + var mountedResponders = Array.from(_respondersMap.keys()); + for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { + var mountedResponder = mountedResponders[_i]; + if (!visistedResponders.has(mountedResponder)) { + var responderInstance = _respondersMap.get(mountedResponder); + unmountResponderInstance(responderInstance); + _respondersMap.delete(mountedResponder); + } + } + } + } +} + +function unwindWork(workInProgress, renderExpirationTime) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; + if (isContextProvider(Component)) { + popContext(workInProgress); + } + var effectTag = workInProgress.effectTag; + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + return null; + } + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; + (function() { + if (!((_effectTag & DidCapture) === NoEffect)) { + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + } + })(); + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var _effectTag2 = workInProgress.effectTag; + if (_effectTag2 & ShouldCapture) { + workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; + // Captured a suspense effect. Re-render the boundary. + return workInProgress; + } + return null; + } + case DehydratedSuspenseComponent: { + if (enableSuspenseServerRenderer) { + // TODO: popHydrationState + popSuspenseContext(workInProgress); + var _effectTag3 = workInProgress.effectTag; + if (_effectTag3 & ShouldCapture) { + workInProgress.effectTag = + (_effectTag3 & ~ShouldCapture) | DidCapture; + // Captured a suspense effect. Re-render the boundary. + return workInProgress; + } + } + 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. + return null; + } + case HostPortal: + popHostContainer(workInProgress); + return null; + case ContextProvider: + popProvider(workInProgress); + return null; + default: + return null; + } +} + +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } + break; + } + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + break; + } + case HostComponent: { + popHostContext(interruptedWork); + break; + } + case HostPortal: + popHostContainer(interruptedWork); + break; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; + case DehydratedSuspenseComponent: + if (enableSuspenseServerRenderer) { + // TODO: popHydrationState + popSuspenseContext(interruptedWork); + } + break; + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; + case ContextProvider: + popProvider(interruptedWork); + break; + default: + break; } - // If it was the primary children that just suspended, capture and render the - // fallback. Otherwise, don't capture and bubble to the next boundary. - var nextState = workInProgress.memoizedState; - return nextState === null; } function createCapturedValue(value, source) { @@ -14403,50 +16994,26 @@ function createCapturedValue(value, source) { source: source, stack: getStackByFiberInDevAndProd(source) }; -} - -// Module provided by RN: -/** - * Intercept lifecycle errors and ensure they are shown with the correct stack - * trace within the native redbox component. - */ -function showErrorDialog(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - - var errorToHandle = void 0; - - // Typically Errors are thrown but eg strings or null can be thrown as well. - if (error instanceof Error) { - var message = error.message, - name = error.name; - - var summary = message ? name + ": " + message : name; - - errorToHandle = error; +} - try { - errorToHandle.message = - summary + "\n\nThis error is located at:" + componentStack; - } catch (e) {} - } else if (typeof error === "string") { - errorToHandle = new Error( - error + "\n\nThis error is located at:" + componentStack +// Module provided by RN: +(function() { + if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog + .showErrorDialog === "function" + ) + ) { + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") ); - } else { - errorToHandle = new Error("Unspecified error at:" + componentStack); } +})(); - ReactNativePrivateInterface.ExceptionsManager.handleException( - errorToHandle, - false +function showErrorDialog(capturedError) { + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError ); - - // Return false here to prevent ReactFiberErrorLogger default behavior of - // logging error details to console.error. Calls to console.error are - // automatically routed to the native redbox controller, which we've already - // done above by calling ExceptionsManager. - return false; } function logCapturedError(capturedError) { @@ -14696,14 +17263,15 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case HostText: case HostPortal: case IncompleteClassComponent: - case EventTarget: // Nothing to do for these component types return; default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -14772,8 +17340,19 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } function commitPassiveHookEffects(finishedWork) { - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if ((finishedWork.effectTag & Passive) !== NoEffect) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + break; + } + default: + break; + } + } } function commitLifeCycles( @@ -14971,73 +17550,43 @@ function commitLifeCycles( if (enableProfilerTimer) { var onRender = finishedWork.memoizedProps.onRender; - if (enableSchedulerTracing) { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime(), - finishedRoot.memoizedInteractions - ); - } else { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime() - ); + if (typeof onRender === "function") { + if (enableSchedulerTracing) { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime(), + finishedRoot.memoizedInteractions + ); + } else { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime() + ); + } } } return; } case SuspenseComponent: + case SuspenseListComponent: case IncompleteClassComponent: + case FundamentalComponent: return; - case EventTarget: { - if (enableEventAPI) { - var _type = finishedWork.type.type; - var _props = finishedWork.memoizedProps; - var _instance3 = finishedWork.stateNode; - var parentInstance = null; - - var node = finishedWork.return; - // Traverse up the fiber tree until we find the parent host node. - while (node !== null) { - if (node.tag === HostComponent) { - parentInstance = node.stateNode; - break; - } else if (node.tag === HostRoot) { - parentInstance = node.stateNode.containerInfo; - break; - } - node = node.return; - } - (function() { - if (!(parentInstance !== null)) { - throw ReactError( - "This should have a parent host component initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); - commitEventTarget(_type, _props, _instance3, parentInstance); - } - return; - } - case EventComponent: { - if (enableEventAPI) { - mountEventComponent(finishedWork.stateNode); - } - return; - } default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15058,11 +17607,11 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { unhideInstance(node.stateNode, node.memoizedProps); } } else if (node.tag === HostText) { - var _instance4 = node.stateNode; + var _instance3 = node.stateNode; if (isHidden) { - hideTextInstance(_instance4); + hideTextInstance(_instance3); } else { - unhideTextInstance(_instance4, node.memoizedProps); + unhideTextInstance(_instance3, node.memoizedProps); } } else if ( node.tag === SuspenseComponent && @@ -15173,6 +17722,25 @@ function commitUnmount(current$$1) { return; } case HostComponent: { + if (enableFlareAPI) { + var dependencies = current$$1.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + for ( + var i = 0, length = responderInstances.length; + i < length; + i++ + ) { + var responderInstance = responderInstances[i]; + unmountResponderInstance(responderInstance); + } + dependencies.responders = null; + } + } + } safelyDetachRef(current$$1); return; } @@ -15187,11 +17755,13 @@ function commitUnmount(current$$1) { } return; } - case EventComponent: { - if (enableEventAPI) { - var eventComponentInstance = current$$1.stateNode; - unmountEventComponent(eventComponentInstance); - current$$1.stateNode = null; + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = current$$1.stateNode; + if (fundamentalInstance !== null) { + unmountFundamentalComponent(fundamentalInstance); + current$$1.stateNode = null; + } } } } @@ -15241,12 +17811,14 @@ function detachFiber(current$$1) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; if (alternate !== null) { alternate.return = null; alternate.child = null; alternate.memoizedState = null; alternate.updateQueue = null; + alternate.dependencies = null; } } @@ -15270,8 +17842,7 @@ function commitContainer(finishedWork) { case ClassComponent: case HostComponent: case HostText: - case EventTarget: - case EventComponent: { + case FundamentalComponent: { return; } case HostRoot: @@ -15286,7 +17857,9 @@ function commitContainer(finishedWork) { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15305,7 +17878,9 @@ function getHostParentFiber(fiber) { (function() { { throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15375,25 +17950,33 @@ function commitPlacement(finishedWork) { // Note: these two variables *must* always be updated together. var parent = void 0; var isContainer = void 0; - + var parentStateNode = parentFiber.stateNode; switch (parentFiber.tag) { case HostComponent: - parent = parentFiber.stateNode; + parent = parentStateNode; isContainer = false; break; case HostRoot: - parent = parentFiber.stateNode.containerInfo; + parent = parentStateNode.containerInfo; isContainer = true; break; case HostPortal: - parent = parentFiber.stateNode.containerInfo; + parent = parentStateNode.containerInfo; isContainer = true; break; + case FundamentalComponent: + if (enableFundamentalAPI) { + parent = parentStateNode.instance; + isContainer = false; + } + // eslint-disable-next-line-no-fallthrough default: (function() { { throw ReactError( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15410,8 +17993,9 @@ function commitPlacement(finishedWork) { // children to find all the terminal nodes. var node = finishedWork; while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - var stateNode = node.stateNode; + var isHost = node.tag === HostComponent || node.tag === HostText; + if (isHost || node.tag === FundamentalComponent) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; if (before) { if (isContainer) { insertInContainerBefore(parent, stateNode, before); @@ -15467,23 +18051,31 @@ function unmountHostComponents(current$$1) { (function() { if (!(parent !== null)) { throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); + var parentStateNode = parent.stateNode; switch (parent.tag) { case HostComponent: - currentParent = parent.stateNode; + currentParent = parentStateNode; currentParentIsContainer = false; break findParent; case HostRoot: - currentParent = parent.stateNode.containerInfo; + currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; case HostPortal: - currentParent = parent.stateNode.containerInfo; + currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; + case FundamentalComponent: + if (enableFundamentalAPI) { + currentParent = parentStateNode.instance; + currentParentIsContainer = false; + } } parent = parent.return; } @@ -15500,6 +18092,16 @@ function unmountHostComponents(current$$1) { removeChild(currentParent, node.stateNode); } // Don't visit children because we already visited them. + } else if (node.tag === FundamentalComponent) { + var fundamentalNode = node.stateNode.instance; + commitNestedUnmounts(node); + // After all the children have unmounted, it is now safe to remove the + // node from the tree. + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, fundamentalNode); + } else { + removeChild(currentParent, fundamentalNode); + } } else if ( enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent @@ -15578,6 +18180,11 @@ function commitWork(current$$1, finishedWork) { } case SuspenseComponent: { commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } } @@ -15630,7 +18237,9 @@ function commitWork(current$$1, finishedWork) { (function() { if (!(finishedWork.stateNode !== null)) { throw ReactError( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15643,9 +18252,6 @@ function commitWork(current$$1, finishedWork) { commitTextUpdate(textInstance, oldText, newText); return; } - case EventTarget: { - return; - } case HostRoot: { return; } @@ -15654,19 +18260,30 @@ function commitWork(current$$1, finishedWork) { } case SuspenseComponent: { commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } case IncompleteClassComponent: { return; } - case EventComponent: { + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = finishedWork.stateNode; + updateFundamentalComponent(fundamentalInstance); + } return; } default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15684,25 +18301,31 @@ function commitSuspenseComponent(finishedWork) { } else { newDidTimeout = true; primaryChildParent = finishedWork.child; - if (newState.fallbackExpirationTime === NoWork) { - // If the children had not already timed out, record the time. - // This is used to compute the elapsed time during subsequent - // attempts to render the children. - // We model this as a normal pri expiration time since that's - // how we infer start time for updates. - newState.fallbackExpirationTime = computeAsyncExpirationNoBucket( - requestCurrentTime() - ); - } + markCommitTimeOfFallback(); } if (supportsMutation && primaryChildParent !== null) { hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); } + if (enableSuspenseCallback && newState !== null) { + var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; + if (typeof suspenseCallback === "function") { + var thenables = finishedWork.updateQueue; + if (thenables !== null) { + suspenseCallback(new Set(thenables)); + } + } else { + if (suspenseCallback !== undefined) { + warning$1(false, "Unexpected type for suspenseCallback."); + } + } + } +} + +function attachSuspenseRetryListeners(finishedWork) { // If this boundary just timed out, then it will have a set of thenables. // For each thenable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. var thenables = finishedWork.updateQueue; if (thenables !== null) { finishedWork.updateQueue = null; @@ -15735,7 +18358,7 @@ var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, null); // Unmount the root by rendering null. update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property @@ -15750,7 +18373,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, null); update.tag = CaptureUpdate; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { @@ -15774,6 +18397,8 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // TODO: Warn in strict mode if getDerivedStateFromError is // not defined. markLegacyErrorBoundaryAsFailed(this); + + // Only log here if componentDidCatch is the only error boundary method defined logError(fiber, errorInfo); } var error = errorInfo.value; @@ -15858,12 +18483,19 @@ function throwException( // This is a thenable. var thenable = value; + checkForWrongSuspensePriorityInDEV(sourceFiber); + + 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) + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) ) { // Found the nearest boundary. @@ -15877,15 +18509,15 @@ function throwException( thenables.add(thenable); } - // If the boundary is outside of concurrent mode, we should *not* + // If the boundary is outside of batched 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 concurrent mode tree. If the Suspense is outside of it, we + // inside a batched mode tree. If the Suspense is outside of it, we // should *not* suspend the commit. - if ((_workInProgress.mode & ConcurrentMode) === NoContext) { + if ((_workInProgress.mode & BatchedMode) === NoMode) { _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete. @@ -15902,9 +18534,9 @@ function throwException( 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 updte to + // since it's known to be in an inconsistent state. Use a force update to // prevent a bail out. - var update = createUpdate(Sync); + var update = createUpdate(Sync, null); update.tag = ForceUpdate; enqueueUpdate(sourceFiber, update); } @@ -15920,11 +18552,51 @@ function throwException( // 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. SuspenseConfig applies 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. attachPingListener(root, renderExpirationTime, thenable); _workInProgress.effectTag |= ShouldCapture; _workInProgress.expirationTime = renderExpirationTime; + return; } else if ( enableSuspenseServerRenderer && @@ -15940,7 +18612,9 @@ function throwException( (function() { if (!current$$1) { throw ReactError( - "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React." + Error( + "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React." + ) ); } })(); @@ -16030,130 +18704,29 @@ function throwException( } while (workInProgress !== null); } -function unwindWork(workInProgress, renderExpirationTime) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; - if (isContextProvider(Component)) { - popContext(workInProgress); - } - var effectTag = workInProgress.effectTag; - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - return null; - } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; - (function() { - if (!((_effectTag & DidCapture) === NoEffect)) { - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - })(); - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; - } - case SuspenseComponent: { - var _effectTag2 = workInProgress.effectTag; - if (_effectTag2 & ShouldCapture) { - workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; - // Captured a suspense effect. Re-render the boundary. - return workInProgress; - } - return null; - } - case DehydratedSuspenseComponent: { - if (enableSuspenseServerRenderer) { - // TODO: popHydrationState - var _effectTag3 = workInProgress.effectTag; - if (_effectTag3 & ShouldCapture) { - workInProgress.effectTag = - (_effectTag3 & ~ShouldCapture) | DidCapture; - // Captured a suspense effect. Re-render the boundary. - return workInProgress; - } - } - return null; - } - case HostPortal: - popHostContainer(workInProgress); - return null; - case ContextProvider: - popProvider(workInProgress); - return null; - case EventComponent: - case EventTarget: - if (enableEventAPI) { - popHostContext(workInProgress); - } - return null; - default: - return null; - } -} - -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); - } - break; - } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - break; - } - case HostComponent: { - popHostContext(interruptedWork); - break; - } - case HostPortal: - popHostContainer(interruptedWork); - break; - case ContextProvider: - popProvider(interruptedWork); - break; - default: - break; - } -} - -// TODO: Ahaha Andrew is bad at spellling // DEV stuff var ceil = Math.ceil; var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; -var ReactShouldWarnActingUpdates = - ReactSharedInternals.ReactShouldWarnActingUpdates; +var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; -var NotWorking = 0; -var BatchedPhase = 1; -var LegacyUnbatchedPhase = 2; -var FlushSyncPhase = 3; -var RenderPhase = 4; -var CommitPhase = 5; +var NoContext = /* */ 0; +var BatchedContext = /* */ 1; +var EventContext = /* */ 2; +var DiscreteEventContext = /* */ 4; +var LegacyUnbatchedContext = /* */ 8; +var RenderContext = /* */ 16; +var CommitContext = /* */ 32; var RootIncomplete = 0; var RootErrored = 1; var RootSuspended = 2; -var RootCompleted = 3; +var RootSuspendedWithDelay = 3; +var RootCompleted = 4; -// The phase of work we're currently in -var workPhase = NotWorking; +// Describes where we are in the React execution stack +var executionContext = NoContext; // The root we're working on var workInProgressRoot = null; // The fiber we're working on @@ -16166,7 +18739,17 @@ var workInProgressRootExitStatus = RootIncomplete; // This is conceptually a time stamp but expressed in terms of an ExpirationTime // because we deal mostly with expiration times in the hot path, so this avoids // the conversion happening in the hot path. -var workInProgressRootMostRecentEventTime = Sync; +var workInProgressRootLatestProcessedExpirationTime = Sync; +var workInProgressRootLatestSuspenseTimeout = Sync; +var workInProgressRootCanSuspendUsingConfig = null; +// If we're pinged while rendering we don't always restart immediately. +// This flag determines if it might be worthwhile to restart if an opportunity +// happens latere. +var workInProgressRootHasPendingPing = false; +// 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; +var FALLBACK_THROTTLE_MS = 500; var nextEffect = null; var hasUncaughtError = false; @@ -16189,6 +18772,12 @@ var nestedPassiveUpdateCount = 0; var interruptedBy = null; +// Marks the need to reschedule pending interactions at these expiration times +// during the commit phase. This enables them to be traced across components +// that spawn new work during render. E.g. hidden boundaries, suspended SSR +// hydration or SuspenseList. +var spawnedWorkDuringRender = null; + // Expiration times are computed by adding to the current time (the start // time). However, if two updates are scheduled within the same event, we // should treat their start times as simultaneous, even if the actual clock @@ -16200,7 +18789,7 @@ var interruptedBy = null; var currentEventTime = NoWork; function requestCurrentTime() { - if (workPhase === RenderPhase || workPhase === CommitPhase) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { // We're inside React, so it's fine to read the actual time. return msToExpirationTime(now()); } @@ -16214,46 +18803,62 @@ function requestCurrentTime() { return currentEventTime; } -function computeExpirationForFiber(currentTime, fiber) { - if ((fiber.mode & ConcurrentMode) === NoContext) { +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + var mode = fiber.mode; + if ((mode & BatchedMode) === NoMode) { return Sync; } - if (workPhase === RenderPhase) { + var priorityLevel = getCurrentPriorityLevel(); + if ((mode & ConcurrentMode) === NoMode) { + return priorityLevel === ImmediatePriority ? Sync : Batched; + } + + if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering return renderExpirationTime; } - // Compute an expiration time based on the Scheduler priority. var expirationTime = void 0; - var priorityLevel = getCurrentPriorityLevel(); - switch (priorityLevel) { - case ImmediatePriority: - expirationTime = Sync; - break; - case UserBlockingPriority: - // TODO: Rename this to computeUserBlockingExpiration - expirationTime = computeInteractiveExpiration(currentTime); - break; - case NormalPriority: - case LowPriority: - // TODO: Handle LowPriority - // TODO: Rename this to... something better. - expirationTime = computeAsyncExpiration(currentTime); - break; - case IdlePriority: - expirationTime = Never; - break; - default: - (function() { - { - throw ReactError("Expected a valid priority level"); - } - })(); + if (suspenseConfig !== null) { + // Compute an expiration time based on the Suspense timeout. + expirationTime = computeSuspenseExpiration( + currentTime, + suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION + ); + } else { + // Compute an expiration time based on the Scheduler priority. + switch (priorityLevel) { + case ImmediatePriority: + expirationTime = Sync; + break; + case UserBlockingPriority$1: + // TODO: Rename this to computeUserBlockingExpiration + expirationTime = computeInteractiveExpiration(currentTime); + break; + case NormalPriority: + case LowPriority: + // TODO: Handle LowPriority + // TODO: Rename this to... something better. + expirationTime = computeAsyncExpiration(currentTime); + break; + case IdlePriority: + expirationTime = Never; + break; + default: + (function() { + { + throw ReactError(Error("Expected a valid priority level")); + } + })(); + } } // If we're in the middle of rendering a tree, do not update at the same // expiration time that is already rendering. + // TODO: We shouldn't have to do this if the update is on a different root. + // Refactor computeExpirationForFiber + scheduleUpdate so we have access to + // the root when we check for this condition. if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; @@ -16277,8 +18882,20 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { checkForInterruption(fiber, expirationTime); recordScheduleUpdate(); + // TODO: computeExpirationForFiber also reads the priority. Pass the + // priority as an argument to that function and this one. + var priorityLevel = getCurrentPriorityLevel(); + if (expirationTime === Sync) { - if (workPhase === LegacyUnbatchedPhase) { + if ( + // Check if we're inside unbatchedUpdates + (executionContext & LegacyUnbatchedContext) !== NoContext && + // Check if we're not already rendering + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + // Register pending interactions on the root to avoid losing traced interaction data. + schedulePendingInteractions(root, expirationTime); + // This is a legacy edge case. The initial mount of a ReactDOM.render-ed // root inside of batchedUpdates should be synchronous, but layout updates // should be deferred until the end of the batch. @@ -16288,35 +18905,36 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { } } else { scheduleCallbackForRoot(root, ImmediatePriority, Sync); - if (workPhase === NotWorking) { + if (executionContext === NoContext) { // Flush the synchronous work now, wnless we're already working or inside // a batch. This is intentionally inside scheduleUpdateOnFiber instead of // scheduleCallbackForFiber to preserve the ability to schedule a callback - // without immediately flushing it. We only do this for user-initated + // without immediately flushing it. We only do this for user-initiated // updates, to preserve historical behavior of sync mode. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } } else { - // TODO: computeExpirationForFiber also reads the priority. Pass the - // priority as an argument to that function and this one. - var priorityLevel = getCurrentPriorityLevel(); - if (priorityLevel === UserBlockingPriority) { - // This is the result of a discrete event. Track the lowest priority - // discrete update per root so we can flush them early, if needed. - if (rootsWithPendingDiscreteUpdates === null) { - rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); - } else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); - if ( - lastDiscreteTime === undefined || - lastDiscreteTime > expirationTime - ) { - rootsWithPendingDiscreteUpdates.set(root, expirationTime); - } + scheduleCallbackForRoot(root, priorityLevel, expirationTime); + } + + 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) + ) { + // This is the result of a discrete event. Track the lowest priority + // discrete update per root so we can flush them early, if needed. + if (rootsWithPendingDiscreteUpdates === null) { + rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); + } else { + var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); + if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) { + rootsWithPendingDiscreteUpdates.set(root, expirationTime); } } - scheduleCallbackForRoot(root, priorityLevel, expirationTime); } } var scheduleWork = scheduleUpdateOnFiber; @@ -16397,42 +19015,46 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { } root.callbackExpirationTime = expirationTime; - var options = null; - if (expirationTime !== Sync && expirationTime !== Never) { - var timeout = expirationTimeToMs(expirationTime) - now(); - if (timeout > 5000) { - // Sanity check. Should never take longer than 5 seconds. - // TODO: Add internal warning? - timeout = 5000; + if (expirationTime === Sync) { + // Sync React callbacks are scheduled on a special internal queue + root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + ); + } else { + var options = null; + if (expirationTime !== Never) { + var timeout = expirationTimeToMs(expirationTime) - now(); + options = { timeout: timeout }; + } + + root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + options + ); + if ( + enableUserTimingAPI && + expirationTime !== Sync && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + // Scheduled an async callback, and we're not already working. Add an + // entry to the flamegraph that shows we're waiting for a callback + // to fire. + startRequestCallbackTimer(); } - options = { timeout: timeout }; - } - - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - options - ); - if ( - enableUserTimingAPI && - expirationTime !== Sync && - workPhase !== RenderPhase && - workPhase !== CommitPhase - ) { - // Scheduled an async callback, and we're not already working. Add an - // entry to the flamegraph that shows we're waiting for a callback - // to fire. - startRequestCallbackTimer(); } } - // Add the current set of interactions to the pending set associated with - // this root. - schedulePendingInteraction(root, expirationTime); + // Associate the current interactions with this new root+priority. + schedulePendingInteractions(root, expirationTime); } function runRootCallback(root, callback, isSync) { @@ -16457,15 +19079,33 @@ function runRootCallback(root, callback, isSync) { } } -function flushInteractiveUpdates$1() { - if (workPhase === RenderPhase || workPhase === CommitPhase) { - // Can't synchronously flush interactive updates if React is already - // working. This is currently a no-op. - // TODO: Should we fire a warning? This happens if you synchronously invoke - // an input event inside an effect, like with `element.click()`. +function flushDiscreteUpdates() { + // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. + // However, `act` uses `batchedUpdates`, so there's no way to distinguish + // those two cases. Need to fix this before exposing flushDiscreteUpdates + // as a public API. + if ( + (executionContext & (BatchedContext | RenderContext | CommitContext)) !== + NoContext + ) { + if (true && (executionContext & RenderContext) !== NoContext) { + warning$1( + false, + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } + // We're already rendering, so we can't synchronously flush pending work. + // This is probably a nested event dispatch triggered by a lifecycle/effect, + // like `el.focus()`. Exit. return; } flushPendingDiscreteUpdates(); + if (!revertPassiveEffectsChange) { + // If the discrete updates scheduled passive effects, flush them now so that + // they fire before the next serial event. + flushPassiveEffects(); + } } function resolveLocksOnRoot(root, expirationTime) { @@ -16475,8 +19115,6 @@ function resolveLocksOnRoot(root, expirationTime) { firstBatch._defer && firstBatch._expirationTime >= expirationTime ) { - root.finishedWork = root.current.alternate; - root.pendingCommitExpirationTime = expirationTime; scheduleCallback(NormalPriority, function() { firstBatch._onComplete(); return null; @@ -16487,15 +19125,6 @@ function resolveLocksOnRoot(root, expirationTime) { } } -function interactiveUpdates$1(fn, a, b, c) { - if (workPhase === NotWorking) { - // TODO: Remove this call. Instead of doing this automatically, the caller - // should explicitly call flushInteractiveUpdates. - flushPendingDiscreteUpdates(); - } - return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); -} - function flushPendingDiscreteUpdates() { if (rootsWithPendingDiscreteUpdates !== null) { // For each root with pending discrete updates, schedule a callback to @@ -16503,56 +19132,84 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback( - ImmediatePriority, - renderRoot.bind(null, root, expirationTime) - ); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); // Now flush the immediate queue. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function batchedUpdates$1(fn, a) { - if (workPhase !== NotWorking) { - // We're already working, or inside a batch, so batchedUpdates is a no-op. + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + try { return fn(a); + } finally { + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } } - workPhase = BatchedPhase; +} + +function batchedEventUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= EventContext; try { return fn(a); } finally { - workPhase = NotWorking; - // Flush the immediate callbacks that were scheduled during this batch - flushImmediateQueue(); + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} + +function discreteUpdates$1(fn, a, b, c) { + var prevExecutionContext = executionContext; + executionContext |= DiscreteEventContext; + try { + // Should this + return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c)); + } finally { + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } } } function flushSync(fn, a) { - if (workPhase === RenderPhase || workPhase === CommitPhase) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { (function() { { throw ReactError( - "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." + Error( + "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." + ) ); } })(); } - var prevWorkPhase = workPhase; - workPhase = FlushSyncPhase; + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; try { - return runWithPriority(ImmediatePriority, fn.bind(null, a)); + return runWithPriority$1(ImmediatePriority, fn.bind(null, a)); } finally { - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up // the stack. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = NoWork; + root.finishedWork = null; + root.finishedExpirationTime = NoWork; var timeoutHandle = root.timeoutHandle; if (timeoutHandle !== noTimeout) { @@ -16574,17 +19231,26 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = Sync; + workInProgressRootLatestProcessedExpirationTime = Sync; + workInProgressRootLatestSuspenseTimeout = Sync; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = false; + + if (enableSchedulerTracing) { + spawnedWorkDuringRender = null; + } { ReactStrictModeWarnings.discardPendingWarnings(); + componentsThatSuspendedAtHighPri = null; + componentsThatTriggeredHighPriSuspend = null; } } function renderRoot(root, expirationTime, isSync) { (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Should not already be working."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError(Error("Should not already be working.")); } })(); @@ -16600,10 +19266,11 @@ function renderRoot(root, expirationTime, isSync) { return null; } - if (root.pendingCommitExpirationTime === expirationTime) { + if (isSync && root.finishedExpirationTime === expirationTime) { // There's already a pending commit at this expiration time. - root.pendingCommitExpirationTime = NoWork; - return commitRoot.bind(null, root, expirationTime); + // TODO: This is poorly factored. This case only exists for the + // batch.commit() API. + return commitRoot.bind(null, root); } flushPassiveEffects(); @@ -16612,14 +19279,34 @@ function renderRoot(root, expirationTime, isSync) { // and prepare a fresh one. Otherwise we'll continue where we left off. if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) { prepareFreshStack(root, expirationTime); - startWorkOnPendingInteraction(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) { + // We could've received an update at a lower priority while we yielded. + // We're suspended in a delayed state. Once we complete this render we're + // just going to try to recover at the last pending time anyway so we might + // as well start doing that eagerly. + // Ideally we should be able to do this even for retries but we don't yet + // know if we're going to process an update which wants to commit earlier, + // and this path happens very early so it would happen too often. Instead, + // for that case, we'll wait until we complete. + if (workInProgressRootHasPendingPing) { + // We have a ping at this expiration. Let's restart to see if we get unblocked. + prepareFreshStack(root, expirationTime); + } else { + var lastPendingTime = root.lastPendingTime; + if (lastPendingTime < expirationTime) { + // There's lower priority work. It might be unsuspended. Try rendering + // at that level immediately, while preserving the position in the queue. + return renderRoot.bind(null, root, lastPendingTime); + } + } } // If we have a work-in-progress fiber, it means there's still work to do // in this root. if (workInProgress !== null) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + var prevExecutionContext = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -16645,8 +19332,8 @@ function renderRoot(root, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) { // Restart at the current time. - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = prevExecutionContext; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; @@ -16670,7 +19357,7 @@ function renderRoot(root, expirationTime, isSync) { break; } catch (thrownValue) { // Reset module-level state that was set during the render phase. - resetContextDependences(); + resetContextDependencies(); resetHooks(); var sourceFiber = workInProgress; @@ -16680,7 +19367,7 @@ function renderRoot(root, expirationTime, isSync) { // supposed to capture all errors that weren't caught by an error // boundary. prepareFreshStack(root, expirationTime); - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; throw thrownValue; } @@ -16703,8 +19390,8 @@ function renderRoot(root, expirationTime, isSync) { } } while (true); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = prevExecutionContext; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; @@ -16724,6 +19411,9 @@ function renderRoot(root, expirationTime, isSync) { // something suspended, wait to commit it after a timeout. stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + var isLocked = resolveLocksOnRoot(root, expirationTime); if (isLocked) { // This root has a lock that prevents it from committing. Exit. If we begin @@ -16735,11 +19425,13 @@ function renderRoot(root, expirationTime, isSync) { // Set this to null to indicate there's no in-progress render. workInProgressRoot = null; + flushSuspensePriorityWarningInDEV(); + switch (workInProgressRootExitStatus) { case RootIncomplete: { (function() { { - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); } })(); } @@ -16749,77 +19441,192 @@ function renderRoot(root, expirationTime, isSync) { case RootErrored: { // An error was thrown. First check if there is lower priority work // scheduled on this root. - var lastPendingTime = root.lastPendingTime; - if (root.lastPendingTime < expirationTime) { + var _lastPendingTime = root.lastPendingTime; + if (_lastPendingTime < expirationTime) { // There's lower priority work. Before raising the error, try rendering // at the lower priority to see if it fixes it. Use a continuation to // maintain the existing priority and position in the queue. - return renderRoot.bind(null, root, lastPendingTime); + return renderRoot.bind(null, root, _lastPendingTime); } if (!isSync) { // If we're rendering asynchronously, it's possible the error was // caused by tearing due to a mutation during an event. Try rendering // one more time without yiedling to events. prepareFreshStack(root, expirationTime); - scheduleCallback( - ImmediatePriority, - renderRoot.bind(null, root, expirationTime) - ); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); return null; } // If we're already rendering synchronously, commit the root in its // errored state. - return commitRoot.bind(null, root, expirationTime); + return commitRoot.bind(null, root); } case RootSuspended: { + // We have an acceptable loading state. We need to figure out if we should + // immediately commit it or wait a bit. + + // If we have processed new updates during this render, we may now have a + // new loading state ready. We want to ensure that we commit that as soon as + // possible. + var hasNotProcessedNewUpdates = + workInProgressRootLatestProcessedExpirationTime === Sync; + if (hasNotProcessedNewUpdates && !isSync) { + // If we have not processed any new updates during this pass, then this is + // either a retry of an existing fallback state or a hidden tree. + // Hidden trees shouldn't be batched with other work and after that's + // fixed it can only be a retry. + // We're going to throttle committing retries so that we don't show too + // many loading states too quickly. + var msUntilTimeout = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); + // Don't bother with a very short suspense time. + if (msUntilTimeout > 10) { + if (workInProgressRootHasPendingPing) { + // This render was pinged but we didn't get to restart earlier so try + // restarting now instead. + prepareFreshStack(root, expirationTime); + return renderRoot.bind(null, root, expirationTime); + } + var _lastPendingTime2 = root.lastPendingTime; + if (_lastPendingTime2 < expirationTime) { + // There's lower priority work. It might be unsuspended. Try rendering + // at that level. + return renderRoot.bind(null, root, _lastPendingTime2); + } + // The render is suspended, it hasn't timed out, and there's no lower + // priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + msUntilTimeout + ); + return null; + } + } + // The work expired. Commit immediately. + return commitRoot.bind(null, root); + } + case RootSuspendedWithDelay: { if (!isSync) { - var _lastPendingTime = root.lastPendingTime; - if (root.lastPendingTime < expirationTime) { + // We're suspended in a state that should be avoided. We'll try to avoid committing + // it for as long as the timeouts let us. + if (workInProgressRootHasPendingPing) { + // This render was pinged but we didn't get to restart earlier so try + // restarting now instead. + prepareFreshStack(root, expirationTime); + return renderRoot.bind(null, root, expirationTime); + } + var _lastPendingTime3 = root.lastPendingTime; + if (_lastPendingTime3 < expirationTime) { // There's lower priority work. It might be unsuspended. Try rendering - // at that level. - return renderRoot.bind(null, root, _lastPendingTime); + // at that level immediately. + return renderRoot.bind(null, root, _lastPendingTime3); } - // If workInProgressRootMostRecentEventTime is Sync, that means we didn't - // track any event times. That can happen if we retried but nothing switched - // from fallback to content. There's no reason to delay doing no work. - if (workInProgressRootMostRecentEventTime !== Sync) { - var msUntilTimeout = computeMsUntilTimeout( - workInProgressRootMostRecentEventTime, - expirationTime + + var _msUntilTimeout = void 0; + if (workInProgressRootLatestSuspenseTimeout !== Sync) { + // We have processed a suspense config whose expiration time we can use as + // the timeout. + _msUntilTimeout = + expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now(); + } else if (workInProgressRootLatestProcessedExpirationTime === Sync) { + // This should never normally happen because only new updates cause + // delayed states, so we should have processed something. However, + // this could also happen in an offscreen tree. + _msUntilTimeout = 0; + } else { + // If we don't have a suspense config, we're going to use a heuristic to + var eventTimeMs = inferTimeFromExpirationTime( + workInProgressRootLatestProcessedExpirationTime ); - // Don't bother with a very short suspense time. - if (msUntilTimeout > 10) { - // The render is suspended, it hasn't timed out, and there's no lower - // priority work to do. Instead of committing the fallback - // immediately, wait for more data to arrive. - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, expirationTime), - msUntilTimeout - ); - return null; + var currentTimeMs = now(); + var timeUntilExpirationMs = + expirationTimeToMs(expirationTime) - currentTimeMs; + var timeElapsed = currentTimeMs - eventTimeMs; + if (timeElapsed < 0) { + // We get this wrong some time since we estimate the time. + timeElapsed = 0; } + + _msUntilTimeout = jnd(timeElapsed) - timeElapsed; + + // Clamp the timeout to the expiration time. + // TODO: Once the event time is exact instead of inferred from expiration time + // we don't need this. + if (timeUntilExpirationMs < _msUntilTimeout) { + _msUntilTimeout = timeUntilExpirationMs; + } + } + + // Don't bother with a very short suspense time. + if (_msUntilTimeout > 10) { + // The render is suspended, it hasn't timed out, and there's no lower + // priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + _msUntilTimeout + ); + return null; } } // The work expired. Commit immediately. - return commitRoot.bind(null, root, expirationTime); + return commitRoot.bind(null, root); } case RootCompleted: { // The work completed. Ready to commit. - return commitRoot.bind(null, root, expirationTime); + if ( + !isSync && + workInProgressRootLatestProcessedExpirationTime !== Sync && + workInProgressRootCanSuspendUsingConfig !== null + ) { + // If we have exceeded the minimum loading delay, which probably + // means we have shown a spinner already, we might have to suspend + // a bit longer to ensure that the spinner is shown for enough time. + var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay( + workInProgressRootLatestProcessedExpirationTime, + expirationTime, + workInProgressRootCanSuspendUsingConfig + ); + if (_msUntilTimeout2 > 10) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + _msUntilTimeout2 + ); + return null; + } + } + return commitRoot.bind(null, root); } default: { (function() { { - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } })(); } } } -function markRenderEventTime(expirationTime) { - if (expirationTime < workInProgressRootMostRecentEventTime) { - workInProgressRootMostRecentEventTime = expirationTime; +function markCommitTimeOfFallback() { + globalMostRecentFallbackTime = now(); +} + +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + if ( + expirationTime < workInProgressRootLatestProcessedExpirationTime && + expirationTime > Never + ) { + workInProgressRootLatestProcessedExpirationTime = expirationTime; + } + if (suspenseConfig !== null) { + if ( + expirationTime < workInProgressRootLatestSuspenseTimeout && + expirationTime > Never + ) { + workInProgressRootLatestSuspenseTimeout = expirationTime; + // Most of the time we only have one config and getting wrong is not bad. + workInProgressRootCanSuspendUsingConfig = suspenseConfig; + } } } @@ -16829,15 +19636,29 @@ function renderDidSuspend() { } } -function renderDidError() { +function renderDidSuspendDelayIfPossible() { if ( workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended ) { + workInProgressRootExitStatus = RootSuspendedWithDelay; + } +} + +function renderDidError() { + if (workInProgressRootExitStatus !== RootCompleted) { workInProgressRootExitStatus = RootErrored; } } +// Called during render to determine if anything has suspended. +// Returns false if we're not sure. +function renderHasNotSuspendedYet() { + // If something errored or completed, we can't really be sure, + // so those are false. + return workInProgressRootExitStatus === RootIncomplete; +} + function inferTimeFromExpirationTime(expirationTime) { // We don't know exactly when the update was scheduled, but we can infer an // approximate start time from the expiration time. @@ -16845,6 +19666,20 @@ function inferTimeFromExpirationTime(expirationTime) { return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION; } +function inferTimeFromExpirationTimeWithSuspenseConfig( + expirationTime, + suspenseConfig +) { + // We don't know exactly when the update was scheduled, but we can infer an + // approximate start time from the expiration time by subtracting the timeout + // that was added to the event time. + var earliestExpirationTimeMs = expirationTimeToMs(expirationTime); + return ( + earliestExpirationTimeMs - + (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) + ); +} + function workLoopSync() { // Already timed out, so perform work without checking if we need to yield. while (workInProgress !== null) { @@ -16869,7 +19704,7 @@ function performUnitOfWork(unitOfWork) { setCurrentFiber(unitOfWork); var next = void 0; - if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoContext) { + if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); @@ -16905,7 +19740,7 @@ function completeUnitOfWork(unitOfWork) { var next = void 0; if ( !enableProfilerTimer || - (workInProgress.mode & ProfileMode) === NoContext + (workInProgress.mode & ProfileMode) === NoMode ) { next = completeWork(current$$1, workInProgress, renderExpirationTime); } else { @@ -16971,7 +19806,7 @@ function completeUnitOfWork(unitOfWork) { if ( enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoContext + (workInProgress.mode & ProfileMode) !== NoMode ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); @@ -17035,7 +19870,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoContext) { + if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -17088,11 +19923,8 @@ function resetChildExpirationTime(completedWork) { completedWork.childExpirationTime = newChildExpirationTime; } -function commitRoot(root, expirationTime) { - runWithPriority( - ImmediatePriority, - commitRootImpl.bind(null, root, expirationTime) - ); +function commitRoot(root) { + runWithPriority$1(ImmediatePriority, commitRootImpl.bind(null, root)); // If there are passive effects, schedule a callback to flush them. This goes // outside commitRootImpl so that it inherits the priority of the render. if (rootWithPendingPassiveEffects !== null) { @@ -17105,19 +19937,31 @@ function commitRoot(root, expirationTime) { return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); flushRenderPhaseStrictModeWarningsInDEV(); (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Should not already be working."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError(Error("Should not already be working.")); } })(); - var finishedWork = root.current.alternate; + + var finishedWork = root.finishedWork; + var expirationTime = root.finishedExpirationTime; + if (finishedWork === null) { + return null; + } + root.finishedWork = null; + root.finishedExpirationTime = NoWork; + (function() { - if (!(finishedWork !== null)) { - throw ReactError("Should have a work-in-progress root."); + if (!(finishedWork !== root.current)) { + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); } })(); @@ -17173,8 +20017,8 @@ function commitRootImpl(root, expirationTime) { } if (firstEffect !== null) { - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + var prevExecutionContext = executionContext; + executionContext |= CommitContext; var prevInteractions = null; if (enableSchedulerTracing) { prevInteractions = tracing.__interactionsRef.current; @@ -17200,7 +20044,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var error = clearCaughtError(); @@ -17226,7 +20070,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var _error = clearCaughtError(); @@ -17261,7 +20105,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var _error2 = clearCaughtError(); @@ -17274,10 +20118,14 @@ function commitRootImpl(root, expirationTime) { nextEffect = null; + // Tell Scheduler to yield at the end of the frame, so the browser has an + // opportunity to paint. + requestPaint(); + if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; } - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; } else { // No effects. root.current = finishedWork; @@ -17297,6 +20145,8 @@ function commitRootImpl(root, expirationTime) { stopCommitTimer(); + var rootDidHavePassiveEffects = rootDoesHavePassiveEffects; + if (rootDoesHavePassiveEffects) { // This commit has passive effects. Stash a reference to them. But don't // schedule a callback until after flushing layout work. @@ -17304,11 +20154,14 @@ function commitRootImpl(root, expirationTime) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsExpirationTime = expirationTime; } else { - if (enableSchedulerTracing) { - // If there are no passive effects, then we can complete the pending - // interactions. Otherwise, we'll wait until after the passive effects - // are flushed. - finishPendingInteractions(root, expirationTime); + // 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; + nextEffect = nextNextEffect; } } @@ -17320,6 +20173,21 @@ function commitRootImpl(root, expirationTime) { currentTime, remainingExpirationTime ); + + if (enableSchedulerTracing) { + if (spawnedWorkDuringRender !== null) { + var expirationTimes = spawnedWorkDuringRender; + spawnedWorkDuringRender = null; + for (var i = 0; i < expirationTimes.length; i++) { + scheduleInteractions( + root, + expirationTimes[i], + root.memoizedInteractions + ); + } + } + } + scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime); } else { // If there's no remaining work, we can clear the set of already failed @@ -17327,7 +20195,17 @@ function commitRootImpl(root, expirationTime) { legacyErrorBoundariesThatAlreadyFailed = null; } - onCommitRoot(finishedWork.stateNode); + if (enableSchedulerTracing) { + if (!rootDidHavePassiveEffects) { + // If there are no passive effects, then we can complete the pending interactions. + // Otherwise, we'll wait until after the passive effects are flushed. + // Wait to do this until after remaining work has been scheduled, + // so that we don't prematurely signal complete for interactions when there's e.g. hidden work. + finishPendingInteractions(root, expirationTime); + } + } + + onCommitRoot(finishedWork.stateNode, expirationTime); if (remainingExpirationTime === Sync) { // Count the number of times the root synchronously re-renders without @@ -17349,7 +20227,7 @@ function commitRootImpl(root, expirationTime) { throw _error3; } - if (workPhase === LegacyUnbatchedPhase) { + if ((executionContext & LegacyUnbatchedContext) !== NoContext) { // This is a legacy edge case. We just committed the initial mount of // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired // synchronously, but layout updates should be deferred until the end @@ -17358,7 +20236,7 @@ function commitRootImpl(root, expirationTime) { } // If layout work was scheduled, flush it now. - flushImmediateQueue(); + flushSyncCallbackQueue(); return null; } @@ -17484,12 +20362,14 @@ function flushPassiveEffects() { } (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Cannot flush passive effects while already rendering."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); } })(); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + var prevExecutionContext = executionContext; + executionContext |= CommitContext; // 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 @@ -17502,7 +20382,7 @@ function flushPassiveEffects() { if (hasCaughtError()) { (function() { if (!(effect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var error = clearCaughtError(); @@ -17510,7 +20390,10 @@ function flushPassiveEffects() { } resetCurrentFiber(); } - effect = effect.nextEffect; + var nextNextEffect = effect.nextEffect; + // Remove nextEffect pointer to assist GC + effect.nextEffect = null; + effect = nextNextEffect; } if (enableSchedulerTracing) { @@ -17518,8 +20401,8 @@ function flushPassiveEffects() { finishPendingInteractions(root, expirationTime); } - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. @@ -17612,9 +20495,32 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { // Received a ping at the same priority level at which we're currently - // rendering. Restart from the root. Don't need to schedule a ping because - // we're already working on this tree. - prepareFreshStack(root, renderExpirationTime); + // rendering. We might want to restart this render. This should mirror + // the logic of whether or not a root suspends once it completes. + + // TODO: If we're rendering sync either due to Sync, Batched or expired, + // we should probably never restart. + + // If we're suspended with delay, we'll always suspend so we can always + // restart. If we're suspended without any updates, it might be a retry. + // If it's early in the retry we can restart. We can't know for sure + // whether we'll eventually process an update during this render pass, + // but it's somewhat unlikely that we get to a ping before that, since + // getting to the root most update is usually very fast. + if ( + workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + workInProgressRootLatestProcessedExpirationTime === Sync && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ) { + // Restart from the root. Don't need to schedule a ping because + // we're already working on this tree. + prepareFreshStack(root, renderExpirationTime); + } else { + // Even though we can't restart right now, we might get an + // opportunity later. So we mark this render as having a ping. + workInProgressRootHasPendingPing = true; + } return; } @@ -17633,6 +20539,12 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { // Mark the time at which this ping was scheduled. root.pingTime = suspendedTime; + if (root.finishedExpirationTime === suspendedTime) { + // If there's a pending fallback waiting to commit, throw it away. + root.finishedExpirationTime = NoWork; + root.finishedWork = null; + } + var currentTime = requestCurrentTime(); var priorityLevel = inferPriorityFromExpirationTime( currentTime, @@ -17642,12 +20554,17 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { } function retryTimedOutBoundary(boundaryFiber) { - // The boundary fiber (a Suspense component) previously timed out and was - // rendered in its fallback state. One of the promises that suspended it has - // resolved, which means at least part of the tree was likely unblocked. Try - // rendering again, at a new expiration time. + // The boundary fiber (a Suspense component or SuspenseList component) + // previously was rendered in its fallback state. One of the promises that + // suspended it has resolved, which means at least part of the tree was + // likely unblocked. Try rendering again, at a new expiration time. var currentTime = requestCurrentTime(); - var retryTime = computeExpirationForFiber(currentTime, boundaryFiber); + var suspenseConfig = null; // Retries don't carry over the already committed update. + var retryTime = computeExpirationForFiber( + currentTime, + boundaryFiber, + suspenseConfig + ); // TODO: Special case idle priority? var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime); var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime); @@ -17670,7 +20587,9 @@ function resolveRetryThenable(boundaryFiber, thenable) { (function() { { throw ReactError( - "Pinged unknown suspense boundary type. This is probably a bug in React." + Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ) ); } })(); @@ -17713,29 +20632,30 @@ function jnd(timeElapsed) { : ceil(timeElapsed / 1960) * 1960; } -function computeMsUntilTimeout(mostRecentEventTime, committedExpirationTime) { - if (disableYielding) { - // Timeout immediately when yielding is disabled. +function computeMsUntilSuspenseLoadingDelay( + mostRecentEventTime, + committedExpirationTime, + suspenseConfig +) { + var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0; + if (busyMinDurationMs <= 0) { return 0; } + var busyDelayMs = suspenseConfig.busyDelayMs | 0; - var eventTimeMs = inferTimeFromExpirationTime(mostRecentEventTime); + // Compute the time until this render pass would expire. var currentTimeMs = now(); + var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig( + mostRecentEventTime, + suspenseConfig + ); var timeElapsed = currentTimeMs - eventTimeMs; - - var msUntilTimeout = jnd(timeElapsed) - timeElapsed; - - // Compute the time until this render pass would expire. - var timeUntilExpirationMs = - expirationTimeToMs(committedExpirationTime) - currentTimeMs; - - // Clamp the timeout to the expiration time. - // TODO: Once the event time is exact instead of inferred from expiration time - // we don't need this. - if (timeUntilExpirationMs < msUntilTimeout) { - msUntilTimeout = timeUntilExpirationMs; + if (timeElapsed <= busyDelayMs) { + // If we haven't yet waited longer than the initial delay, we don't + // have to wait any additional time. + return 0; } - + var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`. return msUntilTimeout; } @@ -17747,7 +20667,9 @@ function checkForNestedUpdates() { (function() { { throw ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) ); } })(); @@ -17769,11 +20691,10 @@ function checkForNestedUpdates() { function flushRenderPhaseStrictModeWarningsInDEV() { { - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); ReactStrictModeWarnings.flushLegacyContextWarning(); if (warnAboutDeprecatedLifecycles) { - ReactStrictModeWarnings.flushPendingDeprecationWarnings(); + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } } @@ -17868,7 +20789,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // Keep this code in sync with renderRoot; any changes here must have // corresponding changes there. - resetContextDependences(); + resetContextDependencies(); resetHooks(); // Unwind the failed stack frame @@ -17940,578 +20861,502 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { } } -function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { - { - if ( - workPhase === NotWorking && - ReactShouldWarnActingUpdates.current === false - ) { - warningWithoutStack$1( - false, - "An update to %s inside a test was not wrapped in act(...).\n\n" + - "When testing, code that causes React state updates should be " + - "wrapped into act(...):\n\n" + - "act(() => {\n" + - " /* fire events that update state */\n" + - "});\n" + - "/* assert on the output */\n\n" + - "This ensures that you're testing the behavior the user would see " + - "in the browser." + - " Learn more at https://fb.me/react-wrap-tests-with-act" + - "%s", - getComponentName(fiber.type), - getStackByFiberInDevAndProd(fiber) - ); - } - } -} - -var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; - -function computeThreadID(root, expirationTime) { - // Interaction threads are unique per root and expiration time. - return expirationTime * 1000 + root.interactionThreadID; -} - -function schedulePendingInteraction(root, expirationTime) { - // This is called when work is scheduled on a root. It sets up a pending - // interaction, which is completed once the work commits. - if (!enableSchedulerTracing) { - return; - } - - var interactions = tracing.__interactionsRef.current; - if (interactions.size > 0) { - var pendingInteractionMap = root.pendingInteractionMap; - var pendingInteractions = pendingInteractionMap.get(expirationTime); - if (pendingInteractions != null) { - interactions.forEach(function(interaction) { - if (!pendingInteractions.has(interaction)) { - // Update the pending async work count for previously unscheduled interaction. - interaction.__count++; - } - - pendingInteractions.add(interaction); - }); - } else { - pendingInteractionMap.set(expirationTime, new Set(interactions)); - - // Update the pending async work count for the current interactions. - interactions.forEach(function(interaction) { - interaction.__count++; - }); - } - - var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { - var threadID = computeThreadID(root, expirationTime); - subscriber.onWorkScheduled(interactions, threadID); - } - } -} - -function startWorkOnPendingInteraction(root, expirationTime) { - // This is called when new work is started on a root. - if (!enableSchedulerTracing) { - return; - } - - // Determine which interactions this batch of work currently includes, So that - // we can accurately attribute time spent working on it, And so that cascading - // work triggered during the render phase will be associated with it. - var interactions = new Set(); - root.pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledExpirationTime - ) { - if (scheduledExpirationTime >= expirationTime) { - scheduledInteractions.forEach(function(interaction) { - return interactions.add(interaction); - }); - } - }); - - // Store the current set of interactions on the FiberRoot for a few reasons: - // We can re-use it in hot functions like renderRoot() without having to - // recalculate it. We will also use it in commitWork() to pass to any Profiler - // onRender() hooks. This also provides DevTools with a way to access it when - // the onCommitRoot() hook is called. - root.memoizedInteractions = interactions; - - if (interactions.size > 0) { - var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { - var threadID = computeThreadID(root, expirationTime); - try { - subscriber.onWorkStarted(interactions, threadID); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } - } - } -} - -function finishPendingInteractions(root, committedExpirationTime) { - if (!enableSchedulerTracing) { - return; - } - - var earliestRemainingTimeAfterCommit = root.firstPendingTime; - - var subscriber = void 0; +var IsThisRendererActing = { current: false }; - try { - subscriber = tracing.__subscriberRef.current; - if (subscriber !== null && root.memoizedInteractions.size > 0) { - var threadID = computeThreadID(root, committedExpirationTime); - subscriber.onWorkStopped(root.memoizedInteractions, threadID); - } - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } finally { - // Clear completed interactions from the pending Map. - // Unless the render was suspended or cascading work was scheduled, - // In which case– leave pending interactions until the subsequent render. - var pendingInteractionMap = root.pendingInteractionMap; - pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledExpirationTime +function warnIfNotScopedWithMatchingAct(fiber) { + { + if ( + warnsIfNotActing === true && + IsSomeRendererActing.current === true && + IsThisRendererActing.current !== true ) { - // Only decrement the pending interaction count if we're done. - // If there's still work at the current priority, - // That indicates that we are waiting for suspense data. - if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { - pendingInteractionMap.delete(scheduledExpirationTime); - - scheduledInteractions.forEach(function(interaction) { - interaction.__count--; - - if (subscriber !== null && interaction.__count === 0) { - try { - subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } - } - }); - } - }); + warningWithoutStack$1( + false, + "It looks like you're using the wrong act() around your test interactions.\n" + + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + + "// for react-dom:\n" + + "import {act} from 'react-dom/test-utils';\n" + + "//...\n" + + "act(() => ...);\n\n" + + "// for react-test-renderer:\n" + + "import TestRenderer from 'react-test-renderer';\n" + + "const {act} = TestRenderer;\n" + + "//...\n" + + "act(() => ...);" + + "%s", + getStackByFiberInDevAndProd(fiber) + ); + } } } -// Resolves type to a family. - -// Used by React Refresh runtime through DevTools Global Hook. - -var resolveFamily = null; -// $FlowFixMe Flow gets confused by a WeakSet feature check below. -var failedBoundaries = null; - -var setRefreshHandler = function(handler) { +function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { - resolveFamily = handler; + if ( + warnsIfNotActing === true && + (fiber.mode & StrictMode) !== NoMode && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); + } } -}; +} -function resolveFunctionForHotReloading(type) { +function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return type; - } - var family = resolveFamily(type); - if (family === undefined) { - return type; + if ( + warnsIfNotActing === true && + executionContext === NoContext && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s inside a test was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); } - // Use the latest known implementation. - return family.current; } } -function resolveClassForHotReloading(type) { - // No implementation differences. - return resolveFunctionForHotReloading(type); -} +var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; -function resolveForwardRefForHotReloading(type) { +var componentsThatSuspendedAtHighPri = null; +var componentsThatTriggeredHighPriSuspend = null; +function checkForWrongSuspensePriorityInDEV(sourceFiber) { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return type; - } - var family = resolveFamily(type); - if (family === undefined) { - // Check if we're dealing with a real forwardRef. Don't want to crash early. - if ( - type !== null && - type !== undefined && - typeof type.render === "function" - ) { - // ForwardRef is special because its resolved .type is an object, - // but it's possible that we only have its inner render function in the map. - // If that inner render function is different, we'll build a new forwardRef type. - var currentRender = resolveFunctionForHotReloading(type.render); - if (type.render !== currentRender) { - var syntheticType = { - $$typeof: REACT_FORWARD_REF_TYPE, - render: currentRender - }; - if (type.displayName !== undefined) { - syntheticType.displayName = type.displayName; + var currentPriorityLevel = getCurrentPriorityLevel(); + if ( + (sourceFiber.mode & ConcurrentMode) !== NoEffect && + (currentPriorityLevel === UserBlockingPriority$1 || + currentPriorityLevel === ImmediatePriority) + ) { + var workInProgressNode = sourceFiber; + while (workInProgressNode !== null) { + // Add the component that triggered the suspense + var current$$1 = workInProgressNode.alternate; + if (current$$1 !== null) { + // TODO: warn component that triggers the high priority + // suspend is the HostRoot + switch (workInProgressNode.tag) { + case ClassComponent: + // Loop through the component's update queue and see whether the component + // has triggered any high priority updates + var updateQueue = current$$1.updateQueue; + if (updateQueue !== null) { + var update = updateQueue.firstUpdate; + while (update !== null) { + var priorityLevel = update.priority; + if ( + priorityLevel === UserBlockingPriority$1 || + priorityLevel === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + break; + } + update = update.next; + } + } + break; + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if ( + workInProgressNode.memoizedState !== null && + workInProgressNode.memoizedState.baseUpdate !== null + ) { + var _update = workInProgressNode.memoizedState.baseUpdate; + // Loop through the functional component's memoized state to see whether + // the component has triggered any high pri updates + while (_update !== null) { + var priority = _update.priority; + if ( + priority === UserBlockingPriority$1 || + priority === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + break; + } + if ( + _update.next === workInProgressNode.memoizedState.baseUpdate + ) { + break; + } + _update = _update.next; + } + } + break; + default: + break; } - return syntheticType; } + workInProgressNode = workInProgressNode.return; + } + + // Add the component name to a set. + var componentName = getComponentName(sourceFiber.type); + if (componentsThatSuspendedAtHighPri === null) { + componentsThatSuspendedAtHighPri = new Set([componentName]); + } else { + componentsThatSuspendedAtHighPri.add(componentName); } - return type; } - // Use the latest known implementation. - return family.current; } } -function isCompatibleFamilyForHotReloading(fiber, element) { +function flushSuspensePriorityWarningInDEV() { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return false; - } - - var prevType = fiber.elementType; - var nextType = element.type; - - // If we got here, we know types aren't === equal. - var needsCompareFamilies = false; - - var $$typeofNextType = - typeof nextType === "object" && nextType !== null - ? nextType.$$typeof - : null; + if (componentsThatSuspendedAtHighPri !== null) { + var componentNames = []; + componentsThatSuspendedAtHighPri.forEach(function(name) { + componentNames.push(name); + }); + componentsThatSuspendedAtHighPri = null; - switch (fiber.tag) { - case ClassComponent: { - if (typeof nextType === "function") { - needsCompareFamilies = true; - } - break; - } - case FunctionComponent: { - if (typeof nextType === "function") { - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - // We don't know the inner type yet. - // We're going to assume that the lazy inner type is stable, - // and so it is sufficient to avoid reconciling it away. - // We're not going to unwrap or actually use the new lazy type. - needsCompareFamilies = true; - } - break; - } - case ForwardRef: { - if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - needsCompareFamilies = true; - } - break; - } - case MemoComponent: - case SimpleMemoComponent: { - if ($$typeofNextType === REACT_MEMO_TYPE) { - // TODO: if it was but can no longer be simple, - // we shouldn't set this. - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - needsCompareFamilies = true; - } - break; + var componentsThatTriggeredSuspendNames = []; + if (componentsThatTriggeredHighPriSuspend !== null) { + componentsThatTriggeredHighPriSuspend.forEach(function(name) { + return componentsThatTriggeredSuspendNames.push(name); + }); } - default: - return false; - } - // Check if both types have a family and it's the same one. - if (needsCompareFamilies) { - // Note: memo() and forwardRef() we'll compare outer rather than inner type. - // This means both of them need to be registered to preserve state. - // If we unwrapped and compared the inner types for wrappers instead, - // then we would risk falsely saying two separate memo(Foo) - // calls are equivalent because they wrap the same Foo function. - var prevFamily = resolveFamily(prevType); - if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { - return true; + componentsThatTriggeredHighPriSuspend = null; + + var componentNamesString = componentNames.sort().join(", "); + var componentThatTriggeredSuspenseError = ""; + if (componentsThatTriggeredSuspendNames.length > 0) { + componentThatTriggeredSuspenseError = + "The following components triggered a user-blocking update:" + + "\n\n" + + " " + + componentsThatTriggeredSuspendNames.sort().join(", ") + + "\n\n" + + "that was then suspended by:" + + "\n\n" + + " " + + componentNamesString; + } else { + componentThatTriggeredSuspenseError = + "A user-blocking update was suspended by:" + + "\n\n" + + " " + + componentNamesString; } + + warningWithoutStack$1( + false, + "%s" + + "\n\n" + + "The fix is to split the update into multiple parts: a user-blocking " + + "update to provide immediate feedback, and another update that " + + "triggers the bulk of the changes." + + "\n\n" + + "Refer to the documentation for useSuspenseTransition to learn how " + + "to implement this pattern.", + // TODO: Add link to React docs with more information, once it exists + componentThatTriggeredSuspenseError + ); } - return false; } } -function markFailedErrorBoundaryForHotReloading(fiber) { - { - if (resolveFamily === null) { - // Hot reloading is disabled. - return; - } - if (typeof WeakSet !== "function") { - return; - } - if (failedBoundaries === null) { - failedBoundaries = new WeakSet(); - } - failedBoundaries.add(fiber); +function computeThreadID(root, expirationTime) { + // Interaction threads are unique per root and expiration time. + return expirationTime * 1000 + root.interactionThreadID; +} + +function markSpawnedWork(expirationTime) { + if (!enableSchedulerTracing) { + return; + } + if (spawnedWorkDuringRender === null) { + spawnedWorkDuringRender = [expirationTime]; + } else { + spawnedWorkDuringRender.push(expirationTime); } } -var scheduleRefresh = function(root, update) { - { - if (resolveFamily === null) { - // Hot reloading is disabled. - return; +function scheduleInteractions(root, expirationTime, interactions) { + if (!enableSchedulerTracing) { + return; + } + + if (interactions.size > 0) { + var pendingInteractionMap = root.pendingInteractionMap; + var pendingInteractions = pendingInteractionMap.get(expirationTime); + if (pendingInteractions != null) { + interactions.forEach(function(interaction) { + if (!pendingInteractions.has(interaction)) { + // Update the pending async work count for previously unscheduled interaction. + interaction.__count++; + } + + pendingInteractions.add(interaction); + }); + } else { + pendingInteractionMap.set(expirationTime, new Set(interactions)); + + // Update the pending async work count for the current interactions. + interactions.forEach(function(interaction) { + interaction.__count++; + }); } - var _staleFamilies = update.staleFamilies, - _updatedFamilies = update.updatedFamilies; - flushPassiveEffects(); - flushSync(function() { - scheduleFibersWithFamiliesRecursively( - root.current, - _updatedFamilies, - _staleFamilies - ); - }); + var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { + var threadID = computeThreadID(root, expirationTime); + subscriber.onWorkScheduled(interactions, threadID); + } } -}; +} -var scheduleRoot = function(root, element) { - { - if (root.context !== emptyContextObject) { - // Super edge case: root has a legacy _renderSubtree context - // but we don't know the parentComponent so we can't pass it. - // Just ignore. We'll delete this with _renderSubtree code path later. - return; - } - flushPassiveEffects(); - updateContainerAtExpirationTime(element, root, null, Sync, null); +function schedulePendingInteractions(root, expirationTime) { + // This is called when work is scheduled on a root. + // It associates the current interactions with the newly-scheduled expiration. + // They will be restored when that expiration is later committed. + if (!enableSchedulerTracing) { + return; } -}; -function scheduleFibersWithFamiliesRecursively( - fiber, - updatedFamilies, - staleFamilies -) { - { - var alternate = fiber.alternate, - child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type; + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); +} - var candidateType = null; - switch (tag) { - case FunctionComponent: - case SimpleMemoComponent: - case ClassComponent: - candidateType = type; - break; - case ForwardRef: - candidateType = type.render; - break; - default: - break; - } +function startWorkOnPendingInteractions(root, expirationTime) { + // This is called when new work is started on a root. + if (!enableSchedulerTracing) { + return; + } - if (resolveFamily === null) { - throw new Error("Expected resolveFamily to be set during hot reload."); + // Determine which interactions this batch of work currently includes, So that + // we can accurately attribute time spent working on it, And so that cascading + // work triggered during the render phase will be associated with it. + var interactions = new Set(); + root.pendingInteractionMap.forEach(function( + scheduledInteractions, + scheduledExpirationTime + ) { + if (scheduledExpirationTime >= expirationTime) { + scheduledInteractions.forEach(function(interaction) { + return interactions.add(interaction); + }); } + }); - var needsRender = false; - var needsRemount = false; - if (candidateType !== null) { - var family = resolveFamily(candidateType); - if (family !== undefined) { - if (staleFamilies.has(family)) { - needsRemount = true; - } else if (updatedFamilies.has(family)) { - needsRender = true; - } - } - } - if (failedBoundaries !== null) { - if ( - failedBoundaries.has(fiber) || - (alternate !== null && failedBoundaries.has(alternate)) - ) { - needsRemount = true; - } - } + // Store the current set of interactions on the FiberRoot for a few reasons: + // We can re-use it in hot functions like renderRoot() without having to + // recalculate it. We will also use it in commitWork() to pass to any Profiler + // onRender() hooks. This also provides DevTools with a way to access it when + // the onCommitRoot() hook is called. + root.memoizedInteractions = interactions; - if (needsRemount) { - fiber._debugNeedsRemount = true; - } - if (needsRemount || needsRender) { - scheduleWork(fiber, Sync); - } - if (child !== null && !needsRemount) { - scheduleFibersWithFamiliesRecursively( - child, - updatedFamilies, - staleFamilies - ); - } - if (sibling !== null) { - scheduleFibersWithFamiliesRecursively( - sibling, - updatedFamilies, - staleFamilies - ); + if (interactions.size > 0) { + var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { + var threadID = computeThreadID(root, expirationTime); + try { + subscriber.onWorkStarted(interactions, threadID); + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } } } } -var findHostInstancesForRefresh = function(root, families) { - { - var hostInstances = new Set(); - var types = new Set( - families.map(function(family) { - return family.current; - }) - ); - findHostInstancesForMatchingFibersRecursively( - root.current, - types, - hostInstances - ); - return hostInstances; +function finishPendingInteractions(root, committedExpirationTime) { + if (!enableSchedulerTracing) { + return; } -}; -function findHostInstancesForMatchingFibersRecursively( - fiber, - types, - hostInstances -) { - { - var child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type; + var earliestRemainingTimeAfterCommit = root.firstPendingTime; - var candidateType = null; - switch (tag) { - case FunctionComponent: - case SimpleMemoComponent: - case ClassComponent: - candidateType = type; - break; - case ForwardRef: - candidateType = type.render; - break; - default: - break; - } + var subscriber = void 0; - var didMatch = false; - if (candidateType !== null) { - if (types.has(candidateType)) { - didMatch = true; - } + try { + subscriber = tracing.__subscriberRef.current; + if (subscriber !== null && root.memoizedInteractions.size > 0) { + var threadID = computeThreadID(root, committedExpirationTime); + subscriber.onWorkStopped(root.memoizedInteractions, threadID); } + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } finally { + // Clear completed interactions from the pending Map. + // Unless the render was suspended or cascading work was scheduled, + // In which case– leave pending interactions until the subsequent render. + var pendingInteractionMap = root.pendingInteractionMap; + pendingInteractionMap.forEach(function( + scheduledInteractions, + scheduledExpirationTime + ) { + // Only decrement the pending interaction count if we're done. + // If there's still work at the current priority, + // That indicates that we are waiting for suspense data. + if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { + pendingInteractionMap.delete(scheduledExpirationTime); - if (didMatch) { - // We have a match. This only drills down to the closest host components. - // There's no need to search deeper because for the purpose of giving - // visual feedback, "flashing" outermost parent rectangles is sufficient. - findHostInstancesForFiberShallowly(fiber, hostInstances); - } else { - // If there's no match, maybe there will be one further down in the child tree. - if (child !== null) { - findHostInstancesForMatchingFibersRecursively( - child, - types, - hostInstances - ); + scheduledInteractions.forEach(function(interaction) { + interaction.__count--; + + if (subscriber !== null && interaction.__count === 0) { + try { + subscriber.onInteractionScheduledWorkCompleted(interaction); + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } + } + }); } - } - - if (sibling !== null) { - findHostInstancesForMatchingFibersRecursively( - sibling, - types, - hostInstances - ); - } + }); } } -function findHostInstancesForFiberShallowly(fiber, hostInstances) { - { - var foundHostInstances = findChildHostInstancesForFiberShallowly( - fiber, - hostInstances - ); - if (foundHostInstances) { - return; +var onCommitFiberRoot = null; +var onCommitFiberUnmount = 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; + } + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + 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) { + { + warningWithoutStack$1( + false, + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://fb.me/react-devtools" + ); } - // If we didn't find any host children, fallback to closest host parent. - var node = fiber; - while (true) { - switch (node.tag) { - case HostComponent: - hostInstances.add(node.stateNode); - return; - case HostPortal: - hostInstances.add(node.stateNode.containerInfo); - return; - case HostRoot: - hostInstances.add(node.stateNode.containerInfo); - return; + // DevTools exists, even though it doesn't support Fiber. + return true; + } + try { + var rendererID = hook.inject(internals); + // We have successfully injected, so now it is safe to set up hooks. + onCommitFiberRoot = function(root, expirationTime) { + try { + var didError = (root.current.effectTag & DidCapture) === DidCapture; + if (enableProfilerTimer) { + var currentTime = requestCurrentTime(); + var priorityLevel = inferPriorityFromExpirationTime( + currentTime, + expirationTime + ); + hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); + } else { + hook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); + } } - if (node.return === null) { - throw new Error("Expected to reach root first."); + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); + } } - node = node.return; + }; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s.", + err + ); } } + // DevTools exists + return true; } -function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { - { - var node = fiber; - var foundHostInstances = false; - while (true) { - if (node.tag === HostComponent) { - // We got a match. - foundHostInstances = true; - hostInstances.add(node.stateNode); - // There may still be more, so keep searching. - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - if (node === fiber) { - return foundHostInstances; - } - while (node.sibling === null) { - if (node.return === null || node.return === fiber) { - return foundHostInstances; - } - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } +function onCommitRoot(root, expirationTime) { + if (typeof onCommitFiberRoot === "function") { + onCommitFiberRoot(root, expirationTime); + } +} + +function onCommitUnmount(fiber) { + if (typeof onCommitFiberUnmount === "function") { + onCommitFiberUnmount(fiber); } - return false; } var hasBadMapPolyfill = void 0; @@ -18562,7 +21407,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.memoizedProps = null; this.updateQueue = null; this.memoizedState = null; - this.contextDependencies = null; + this.dependencies = null; this.mode = mode; @@ -18722,7 +21567,19 @@ function createWorkInProgress(current, pendingProps, expirationTime) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + + // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + expirationTime: currentDependencies.expirationTime, + firstContext: currentDependencies.firstContext, + listeners: currentDependencies.listeners, + responders: currentDependencies.responders + }; // These will be overridden during the parent's reconciliation workInProgress.sibling = current.sibling; @@ -18756,8 +21613,87 @@ function createWorkInProgress(current, pendingProps, expirationTime) { return workInProgress; } -function createHostRootFiber(isConcurrent) { - var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext; +// Used to reuse a Fiber for a second pass. +function resetWorkInProgress(workInProgress, renderExpirationTime) { + // This resets the Fiber to what createFiber or createWorkInProgress would + // have set the values to before during the first pass. Ideally this wouldn't + // be necessary but unfortunately many code paths reads from the workInProgress + // 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 + // that child fiber is setting, not the reconciliation. + workInProgress.effectTag &= Placement; + + // The effect list is no longer valid. + workInProgress.nextEffect = null; + workInProgress.firstEffect = null; + workInProgress.lastEffect = null; + + var current = workInProgress.alternate; + if (current === null) { + // Reset to createFiber's initial values. + workInProgress.childExpirationTime = NoWork; + workInProgress.expirationTime = renderExpirationTime; + + workInProgress.child = null; + workInProgress.memoizedProps = null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + + workInProgress.dependencies = null; + + if (enableProfilerTimer) { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = 0; + workInProgress.treeBaseDuration = 0; + } + } else { + // Reset to the cloned values that createWorkInProgress would've. + workInProgress.childExpirationTime = current.childExpirationTime; + workInProgress.expirationTime = current.expirationTime; + + workInProgress.child = current.child; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; + + // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + expirationTime: currentDependencies.expirationTime, + firstContext: currentDependencies.firstContext, + listeners: currentDependencies.listeners, + responders: currentDependencies.responders + }; + + if (enableProfilerTimer) { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; + } + } + + return workInProgress; +} + +function createHostRootFiber(tag) { + var mode = void 0; + if (tag === ConcurrentRoot) { + mode = ConcurrentMode | BatchedMode | StrictMode; + } else if (tag === BatchedRoot) { + mode = BatchedMode | StrictMode; + } else { + mode = NoMode; + } if (enableProfilerTimer && isDevToolsPresent) { // Always collect profile timings when DevTools are present. @@ -18805,23 +21741,24 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode( - pendingProps, - mode | ConcurrentMode | StrictMode, - expirationTime, - key - ); + fiberTag = Mode; + mode |= ConcurrentMode | BatchedMode | StrictMode; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode( - pendingProps, - mode | StrictMode, - expirationTime, - key - ); + fiberTag = Mode; + mode |= StrictMode; + break; case REACT_PROFILER_TYPE: return createFiberFromProfiler(pendingProps, mode, expirationTime, key); case REACT_SUSPENSE_TYPE: return createFiberFromSuspense(pendingProps, mode, expirationTime, key); + case REACT_SUSPENSE_LIST_TYPE: + return createFiberFromSuspenseList( + pendingProps, + mode, + expirationTime, + key + ); default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -18845,20 +21782,9 @@ function createFiberFromTypeAndProps( fiberTag = LazyComponent; resolvedType = null; break getTag; - case REACT_EVENT_COMPONENT_TYPE: - if (enableEventAPI) { - return createFiberFromEventComponent( - type, - pendingProps, - mode, - expirationTime, - key - ); - } - break; - case REACT_EVENT_TARGET_TYPE: - if (enableEventAPI) { - return createFiberFromEventTarget( + case REACT_FUNDAMENTAL_TYPE: + if (enableFundamentalAPI) { + return createFiberFromFundamental( type, pendingProps, mode, @@ -18890,10 +21816,12 @@ function createFiberFromTypeAndProps( (function() { { throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (type == null ? type : typeof type) + - "." + - info + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (type == null ? type : typeof type) + + "." + + info + ) ); } })(); @@ -18938,35 +21866,17 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { return fiber; } -function createFiberFromEventComponent( - eventComponent, - pendingProps, - mode, - expirationTime, - key -) { - var fiber = createFiber(EventComponent, pendingProps, key, mode); - fiber.elementType = eventComponent; - fiber.type = eventComponent; - fiber.expirationTime = expirationTime; - return fiber; -} - -function createFiberFromEventTarget( - eventTarget, +function createFiberFromFundamental( + fundamentalComponent, pendingProps, mode, expirationTime, key ) { - var fiber = createFiber(EventTarget, pendingProps, key, mode); - fiber.elementType = eventTarget; - fiber.type = eventTarget; + var fiber = createFiber(FundamentalComponent, pendingProps, key, mode); + fiber.elementType = fundamentalComponent; + fiber.type = fundamentalComponent; fiber.expirationTime = expirationTime; - // Store latest props - fiber.stateNode = { - props: pendingProps - }; return fiber; } @@ -18992,29 +21902,28 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { return fiber; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - var fiber = createFiber(Mode, pendingProps, key, mode); +function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { + var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); - // TODO: The Mode fiber shouldn't have a type. It has a tag. - var type = - (mode & ConcurrentMode) === NoContext - ? REACT_STRICT_MODE_TYPE - : REACT_CONCURRENT_MODE_TYPE; - fiber.elementType = type; - fiber.type = type; + // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + fiber.type = REACT_SUSPENSE_TYPE; + fiber.elementType = REACT_SUSPENSE_TYPE; fiber.expirationTime = expirationTime; return fiber; } -function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { - var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); - - // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. - var type = REACT_SUSPENSE_TYPE; - fiber.elementType = type; - fiber.type = type; - +function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) { + var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode); + { + // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + fiber.type = REACT_SUSPENSE_LIST_TYPE; + } + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; fiber.expirationTime = expirationTime; return fiber; } @@ -19026,7 +21935,7 @@ function createFiberFromText(content, mode, expirationTime) { } function createFiberFromHostInstanceForDeletion() { - var fiber = createFiber(HostComponent, null, null, NoContext); + var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. fiber.elementType = "DELETED"; fiber.type = "DELETED"; @@ -19050,7 +21959,7 @@ function assignFiberPropertiesInDEV(target, source) { if (target === null) { // This Fiber's initial properties will always be overwritten. // We only use a Fiber to ensure the same hidden class so DEV isn't slow. - target = createFiber(IndeterminateComponent, null, null, NoContext); + target = createFiber(IndeterminateComponent, null, null, NoMode); } // This is intentionally written as a list of all properties. @@ -19073,7 +21982,7 @@ function assignFiberPropertiesInDEV(target, source) { target.memoizedProps = source.memoizedProps; target.updateQueue = source.updateQueue; target.memoizedState = source.memoizedState; - target.contextDependencies = source.contextDependencies; + target.dependencies = source.dependencies; target.mode = source.mode; target.effectTag = source.effectTag; target.nextEffect = source.nextEffect; @@ -19110,12 +22019,13 @@ function assignFiberPropertiesInDEV(target, source) { // The types are defined separately within this file to ensure they stay in sync. // (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.) -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pendingChildren = null; this.pingCache = null; - this.pendingCommitExpirationTime = NoWork; + this.finishedExpirationTime = NoWork; this.finishedWork = null; this.timeoutHandle = noTimeout; this.context = null; @@ -19135,12 +22045,12 @@ function FiberRootNode(containerInfo, hydrate) { } } -function createFiberRoot(containerInfo, isConcurrent, hydrate) { - var root = new FiberRootNode(containerInfo, hydrate); +function createFiberRoot(containerInfo, tag, hydrate) { + var root = new FiberRootNode(containerInfo, tag, hydrate); // Cyclic construction. This cheats the type system right now because // stateNode is any. - var uninitializedFiber = createHostRootFiber(isConcurrent); + var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -19186,7 +22096,13 @@ function getContextForSubtree(parentComponent) { return parentContext; } -function scheduleRootUpdate(current$$1, element, expirationTime, callback) { +function scheduleRootUpdate( + current$$1, + element, + expirationTime, + suspenseConfig, + callback +) { { if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; @@ -19201,7 +22117,7 @@ function scheduleRootUpdate(current$$1, element, expirationTime, callback) { } } - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property // being called "element". update.payload = { element: element }; @@ -19219,7 +22135,9 @@ function scheduleRootUpdate(current$$1, element, expirationTime, callback) { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(current$$1, update); scheduleWork(current$$1, expirationTime); @@ -19231,6 +22149,7 @@ function updateContainerAtExpirationTime( container, parentComponent, expirationTime, + suspenseConfig, callback ) { // TODO: If this is a nested container, this won't be the root. @@ -19255,7 +22174,13 @@ function updateContainerAtExpirationTime( container.pendingContext = context; } - return scheduleRootUpdate(current$$1, element, expirationTime, callback); + return scheduleRootUpdate( + current$$1, + element, + expirationTime, + suspenseConfig, + callback + ); } function findHostInstance(component) { @@ -19264,15 +22189,19 @@ function findHostInstance(component) { if (typeof component.render === "function") { (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } else { (function() { { throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } })(); @@ -19292,15 +22221,19 @@ function findHostInstanceWithWarning(component, methodName) { if (typeof component.render === "function") { (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } else { (function() { { throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } })(); @@ -19350,19 +22283,31 @@ function findHostInstanceWithWarning(component, methodName) { return findHostInstance(component); } -function createContainer(containerInfo, isConcurrent, hydrate) { - return createFiberRoot(containerInfo, isConcurrent, hydrate); +function createContainer(containerInfo, tag, hydrate) { + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current; var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, current$$1); + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(current$$1); + } + } + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); return updateContainerAtExpirationTime( element, container, parentComponent, expirationTime, + suspenseConfig, callback ); } @@ -19419,7 +22364,9 @@ var setSuspenseHandler = null; id--; } if (currentHook !== null) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } var newState = copyWithSet(currentHook.memoizedState, path, value); currentHook.memoizedState = newState; @@ -19438,7 +22385,9 @@ var setSuspenseHandler = null; // Support DevTools props for function components, forwardRef, memo, host components, etc. overrideProps = function(fiber, path, value) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); if (fiber.alternate) { fiber.alternate.pendingProps = fiber.pendingProps; @@ -19447,7 +22396,9 @@ var setSuspenseHandler = null; }; scheduleUpdate = function(fiber) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } scheduleWork(fiber, Sync); }; @@ -19486,7 +22437,11 @@ function injectIntoDevTools(devToolsConfig) { findHostInstancesForRefresh: findHostInstancesForRefresh, scheduleRefresh: scheduleRefresh, scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: function() { + return current; + } }) ); } @@ -19803,7 +22758,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps ) ) { - throw ReactError("Do not override existing functions."); + throw ReactError(Error("Do not override existing functions.")); } })(); // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, @@ -19833,13 +22788,13 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { return NativeMethodsMixin; }; -function _classCallCheck$1(instance, Constructor) { +function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _possibleConstructorReturn(self, call) { +function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError( "this hasn't been initialised - super() hasn't been called" @@ -19850,7 +22805,7 @@ function _possibleConstructorReturn(self, call) { : self; } -function _inherits(subClass, superClass) { +function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError( "Super expression must either be null or a function, not " + @@ -19872,7 +22827,7 @@ function _inherits(subClass, superClass) { } // Modules provided by RN: -var ReactNativeComponent = function(findNodeHandle, findHostInstance) { +var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { /** * Superclass that provides methods to access the underlying native component. * This can be useful when you want to focus a view or measure its dimensions. @@ -19885,12 +22840,12 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { * @abstract */ var ReactNativeComponent = (function(_React$Component) { - _inherits(ReactNativeComponent, _React$Component); + _inherits$1(ReactNativeComponent, _React$Component); function ReactNativeComponent() { - _classCallCheck$1(this, ReactNativeComponent); + _classCallCheck$2(this, ReactNativeComponent); - return _possibleConstructorReturn( + return _possibleConstructorReturn$1( this, _React$Component.apply(this, arguments) ); @@ -20160,16 +23115,16 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { return ReactNativeComponent; }; -var instanceCache = {}; +var instanceCache = new Map(); function getInstanceFromTag(tag) { - return instanceCache[tag] || null; + return instanceCache.get(tag) || null; } // Module provided by RN: -var emptyObject$1 = {}; +var emptyObject$2 = {}; { - Object.freeze(emptyObject$1); + Object.freeze(emptyObject$2); } var getInspectorDataForViewTag = void 0; @@ -20202,9 +23157,9 @@ var getInspectorDataForViewTag = void 0; var getHostProps = function(fiber) { var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$1; + return host.memoizedProps || emptyObject$2; } - return emptyObject$1; + return emptyObject$2; }; var getHostNode = function(fiber, findNodeHandle) { @@ -20250,7 +23205,7 @@ var getInspectorDataForViewTag = void 0; if (!closestInstance) { return { hierarchy: [], - props: emptyObject$1, + props: emptyObject$2, selection: null, source: null }; @@ -20273,6 +23228,9 @@ var getInspectorDataForViewTag = void 0; }; } +var _nativeFabricUIManage = nativeFabricUIManager; +var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand; + var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function findNodeHandle(componentOrHandle) { @@ -20329,14 +23287,15 @@ function findNodeHandle(componentOrHandle) { setBatchingImplementation( batchedUpdates$1, - interactiveUpdates$1, - flushInteractiveUpdates$1 + discreteUpdates$1, + flushDiscreteUpdates, + batchedEventUpdates$1 ); var roots = new Map(); var ReactFabric = { - NativeComponent: ReactNativeComponent(findNodeHandle, findHostInstance), + NativeComponent: ReactNativeComponent$1(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, @@ -20348,13 +23307,34 @@ var ReactFabric = { return; }, + dispatchCommand: function(handle, command, args) { + var invalid = + handle._nativeTag == null || handle._internalInstanceHandle == null; + + if (invalid) { + !!invalid + ? warningWithoutStack$1( + false, + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ) + : void 0; + return; + } + + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); 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, false, false); + root = createContainer(containerTag, LegacyRoot, false); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.js b/Libraries/Renderer/implementations/ReactFabric-dev.js index 8d8d3d59806aa6..6baec3d6a0dc18 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -19,16 +19,15 @@ if (__DEV__) { require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); var React = require("react"); -var checkPropTypes = require("prop-types/checkPropTypes"); var Scheduler = require("scheduler"); +var checkPropTypes = require("prop-types/checkPropTypes"); var tracing = require("scheduler/tracing"); -// Do not require this module directly! Use a normal error constructor with +// Do not require this module directly! Use normal `invariant` calls with // template literal strings. The messages will be converted to ReactError during // build, and in production they will be minified. -function ReactError(message) { - var error = new Error(message); +function ReactError(error) { error.name = "Invariant Violation"; return error; } @@ -70,9 +69,11 @@ function recomputePluginOrdering() { (function() { if (!(pluginIndex > -1)) { throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); } })(); @@ -82,9 +83,11 @@ function recomputePluginOrdering() { (function() { if (!pluginModule.extractEvents) { throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); } })(); @@ -100,11 +103,13 @@ function recomputePluginOrdering() { ) ) { throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } })(); @@ -124,9 +129,11 @@ function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { (function() { if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ) ); } })(); @@ -167,9 +174,11 @@ function publishRegistrationName(registrationName, pluginModule, eventName) { (function() { if (!!registrationNameModules[registrationName]) { throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); } })(); @@ -230,7 +239,9 @@ function injectEventPluginOrder(injectedEventPluginOrder) { (function() { if (!!eventPluginOrder) { throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); } })(); @@ -263,9 +274,11 @@ function injectEventPluginsByName(injectedNamesToPlugins) { (function() { if (!!namesToPlugins[pluginName]) { throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); } })(); @@ -345,7 +358,9 @@ var invokeGuardedCallbackImpl = function( (function() { if (!(typeof document !== "undefined")) { throw ReactError( - "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." + Error( + "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." + ) ); } })(); @@ -574,7 +589,9 @@ function clearCaughtError() { (function() { { throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -788,7 +805,7 @@ function executeDirectDispatch(event) { var dispatchInstance = event._dispatchInstances; (function() { if (!!Array.isArray(dispatchListener)) { - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); } })(); event.currentTarget = dispatchListener @@ -826,7 +843,9 @@ function accumulateInto(current, next) { (function() { if (!(next != null)) { throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); } })(); @@ -914,7 +933,9 @@ function runEventsInBatch(events) { (function() { if (!!eventQueue) { throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); } })(); @@ -1015,11 +1036,13 @@ function getListener(inst, registrationName) { (function() { if (!(!listener || typeof listener === "function")) { throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); } })(); @@ -1092,8 +1115,8 @@ var SimpleMemoComponent = 15; var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedSuspenseComponent = 18; -var EventComponent = 19; -var EventTarget = 20; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; function getParent(inst) { do { @@ -1615,7 +1638,9 @@ function releasePooledEvent(event) { (function() { if (!(event instanceof EventConstructor)) { throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); } })(); @@ -1727,7 +1752,7 @@ function getTouchIdentifier(_ref) { (function() { if (!(identifier != null)) { - throw ReactError("Touch object is missing identifier."); + throw ReactError(Error("Touch object is missing identifier.")); } })(); { @@ -1767,7 +1792,7 @@ function recordTouchMove(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.error( + console.warn( "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -1788,7 +1813,7 @@ function recordTouchEnd(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.error( + console.warn( "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -1860,7 +1885,9 @@ function accumulate(current, next) { (function() { if (!(next != null)) { throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error( + "accumulate(...): Accumulated items must not be null or undefined." + ) ); } })(); @@ -2484,7 +2511,9 @@ var ReactNativeBridgeEventPlugin = { (function() { if (!(bubbleDispatchConfig || directDispatchConfig)) { throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); } })(); @@ -2539,7 +2568,7 @@ function getTagFromInstance(inst) { var tag = inst.stateNode.canonical._nativeTag; (function() { if (!tag) { - throw ReactError("All native instances should have a tag."); + throw ReactError(Error("All native instances should have a tag.")); } })(); return tag; @@ -2609,6 +2638,11 @@ if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { current: null }; } +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. @@ -2623,6 +2657,8 @@ var REACT_STRICT_MODE_TYPE = hasSymbol var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; +// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") @@ -2631,19 +2667,15 @@ var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 0xead0; var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -var REACT_EVENT_COMPONENT_TYPE = hasSymbol - ? Symbol.for("react.event_component") +var REACT_FUNDAMENTAL_TYPE = hasSymbol + ? Symbol.for("react.fundamental") : 0xead5; -var REACT_EVENT_TARGET_TYPE = hasSymbol - ? Symbol.for("react.event_target") - : 0xead6; - -// React event targets -var REACT_EVENT_TARGET_TOUCH_HIT = hasSymbol - ? Symbol.for("react.event_target.touch_hit") - : 0xead7; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; @@ -2669,22 +2701,6 @@ function refineResolvedLazyComponent(lazyComponent) { return lazyComponent._status === Resolved ? lazyComponent._result : null; } -var debugRenderPhaseSideEffects = false; -var debugRenderPhaseSideEffectsForStrictMode = false; -var enableUserTimingAPI = true; -var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; -var warnAboutDeprecatedLifecycles = true; -var enableProfilerTimer = true; -var enableSchedulerTracing = true; -var enableSuspenseServerRenderer = false; - -var disableYielding = false; - -var warnAboutDeprecatedSetNativeProps = false; -var enableEventAPI = false; - -// Only used in www builds. - function getWrappedName(outerType, innerType, wrapperName) { var functionName = innerType.displayName || innerType.name || ""; return ( @@ -2714,8 +2730,6 @@ function getComponentName(type) { return type; } switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -2726,6 +2740,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if (typeof type === "object") { switch (type.$$typeof) { @@ -2745,28 +2761,6 @@ function getComponentName(type) { } break; } - case REACT_EVENT_COMPONENT_TYPE: { - if (enableEventAPI) { - var eventComponent = type; - var displayName = eventComponent.displayName; - if (displayName !== undefined) { - return displayName; - } - } - break; - } - case REACT_EVENT_TARGET_TYPE: { - if (enableEventAPI) { - var eventTarget = type; - if (eventTarget.type === REACT_EVENT_TARGET_TOUCH_HIT) { - return "TouchHitTarget"; - } - var _displayName = eventTarget.displayName; - if (_displayName !== undefined) { - return _displayName; - } - } - } } } return null; @@ -2867,7 +2861,7 @@ function isMounted(component) { function assertIsMounted(fiber) { (function() { if (!(isFiberMountedImpl(fiber) === MOUNTED)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } })(); } @@ -2879,7 +2873,9 @@ function findCurrentFiberUsingSlowPath(fiber) { var state = isFiberMountedImpl(fiber); (function() { if (!(state !== UNMOUNTED)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); if (state === MOUNTING) { @@ -2935,7 +2931,9 @@ function findCurrentFiberUsingSlowPath(fiber) { // way this could possibly happen is if this was unmounted, if at all. (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } @@ -2991,7 +2989,9 @@ function findCurrentFiberUsingSlowPath(fiber) { (function() { if (!didFindChild) { throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } })(); @@ -3001,7 +3001,9 @@ function findCurrentFiberUsingSlowPath(fiber) { (function() { if (!(a.alternate === b)) { throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -3010,7 +3012,7 @@ function findCurrentFiberUsingSlowPath(fiber) { // unmounted. (function() { if (!(a.tag === HostRoot)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } })(); if (a.stateNode.current === a) { @@ -3576,7 +3578,9 @@ function restoreStateOfTarget(target) { (function() { if (!(typeof restoreImpl === "function")) { throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -3605,6 +3609,26 @@ function restoreStateIfNeeded() { } } +var debugRenderPhaseSideEffects = false; +var debugRenderPhaseSideEffectsForStrictMode = false; +var enableUserTimingAPI = true; +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; +var warnAboutDeprecatedLifecycles = true; +var enableProfilerTimer = true; +var enableSchedulerTracing = true; +var enableSuspenseServerRenderer = false; + +var warnAboutDeprecatedSetNativeProps = false; +var enableFlareAPI = false; +var enableFundamentalAPI = false; + +var revertPassiveEffectsChange = false; +var enableUserBlockingEvents = false; +var enableSuspenseCallback = false; +var warnAboutDefaultPropsOnFunctionComponents = false; + +// Only used in www builds. + // Used as a way to call batchedUpdates when we don't have a reference to // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when @@ -3612,632 +3636,1486 @@ function restoreStateIfNeeded() { // scheduled work and instead do synchronous work. // Defaults -var _batchedUpdatesImpl = function(fn, bookkeeping) { +var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; -var _flushInteractiveUpdatesImpl = function() {}; +var discreteUpdatesImpl = function(fn, a, b, c) { + return fn(a, b, c); +}; +var flushDiscreteUpdatesImpl = function() {}; +var batchedEventUpdatesImpl = batchedUpdatesImpl; + +var isInsideEventHandler = false; + +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} -var isBatching = false; function batchedUpdates(fn, bookkeeping) { - if (isBatching) { + if (isInsideEventHandler) { // If we are currently inside another batch, we need to wait until it // fully completes before restoring state. return fn(bookkeeping); } - isBatching = true; + isInsideEventHandler = true; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - // Here we wait until all updates have propagated, which is important - // when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - // Then we restore state of any controlled component. - isBatching = false; - var controlledComponentsHavePendingUpdates = needsStateRestore(); - if (controlledComponentsHavePendingUpdates) { - // If a controlled event was fired, we may need to restore the state of - // the DOM node back to the controlled value. This is necessary when React - // bails out of the update without touching the DOM. - _flushInteractiveUpdatesImpl(); - restoreStateIfNeeded(); - } + isInsideEventHandler = false; + finishEventHandler(); } } -function setBatchingImplementation( - batchedUpdatesImpl, - interactiveUpdatesImpl, - flushInteractiveUpdatesImpl -) { - _batchedUpdatesImpl = batchedUpdatesImpl; - _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; -} - -function dispatchEvent(target, topLevelType, nativeEvent) { - var targetFiber = target; - batchedUpdates(function() { - runExtractedPluginEventsInBatch( - topLevelType, - targetFiber, - nativeEvent, - nativeEvent.target - ); - }); - // React Native doesn't use ReactControlledComponent but if it did, here's - // where it would do it. +function batchedEventUpdates(fn, a, b) { + if (isInsideEventHandler) { + // If we are currently inside another batch, we need to wait until it + // fully completes before restoring state. + return fn(a, b); + } + isInsideEventHandler = true; + try { + return batchedEventUpdatesImpl(fn, a, b); + } finally { + isInsideEventHandler = false; + finishEventHandler(); + } } -// Renderers that don't support mutation -// can re-export everything from this module. - -function shim() { - (function() { - { - throw ReactError( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); +function discreteUpdates(fn, a, b, c) { + var prevIsInsideEventHandler = isInsideEventHandler; + isInsideEventHandler = true; + try { + return discreteUpdatesImpl(fn, a, b, c); + } finally { + isInsideEventHandler = prevIsInsideEventHandler; + if (!isInsideEventHandler) { + finishEventHandler(); + } + } +} + +var lastFlushedEventTimeStamp = 0; +function flushDiscreteUpdatesIfNeeded(timeStamp) { + // event.timeStamp isn't overly reliable due to inconsistencies in + // how different browsers have historically provided the time stamp. + // Some browsers provide high-resolution time stamps for all events, + // some provide low-resolution time stamps for all events. FF < 52 + // even mixes both time stamps together. Some browsers even report + // negative time stamps or time stamps that are 0 (iOS9) in some cases. + // Given we are only comparing two time stamps with equality (!==), + // we are safe from the resolution differences. If the time stamp is 0 + // we bail-out of preventing the flush, which can affect semantics, + // such as if an earlier flush removes or adds event listeners that + // are fired in the subsequent flush. However, this is the same + // behaviour as we had before this change, so the risks are low. + if ( + !isInsideEventHandler && + (!enableFlareAPI || + timeStamp === 0 || + lastFlushedEventTimeStamp !== timeStamp) + ) { + lastFlushedEventTimeStamp = timeStamp; + flushDiscreteUpdatesImpl(); + } } -// Mutation (when unsupported) -var supportsMutation = false; -var appendChild = shim; -var appendChildToContainer = shim; -var commitTextUpdate = shim; -var commitMount = shim; -var commitUpdate = shim; -var insertBefore = shim; -var insertInContainerBefore = shim; -var removeChild = shim; -var removeChildFromContainer = shim; -var resetTextContent = shim; -var hideInstance = shim; -var hideTextInstance = shim; -var unhideInstance = shim; -var unhideTextInstance = shim; - -// Renderers that don't support hydration -// can re-export everything from this module. - -function shim$1() { - (function() { - { - throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); +function setBatchingImplementation( + _batchedUpdatesImpl, + _discreteUpdatesImpl, + _flushDiscreteUpdatesImpl, + _batchedEventUpdatesImpl +) { + batchedUpdatesImpl = _batchedUpdatesImpl; + discreteUpdatesImpl = _discreteUpdatesImpl; + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; + batchedEventUpdatesImpl = _batchedEventUpdatesImpl; } -// Hydration (when unsupported) - -var supportsHydration = false; -var canHydrateInstance = shim$1; -var canHydrateTextInstance = shim$1; -var canHydrateSuspenseInstance = shim$1; -var isSuspenseInstancePending = shim$1; -var isSuspenseInstanceFallback = shim$1; -var registerSuspenseInstanceRetry = shim$1; -var getNextHydratableSibling = shim$1; -var getFirstHydratableChild = shim$1; -var hydrateInstance = shim$1; -var hydrateTextInstance = shim$1; -var getNextHydratableInstanceAfterSuspenseInstance = shim$1; -var clearSuspenseBoundary = shim$1; -var clearSuspenseBoundaryFromContainer = shim$1; -var didNotMatchHydratedContainerTextInstance = shim$1; -var didNotMatchHydratedTextInstance = shim$1; -var didNotHydrateContainerInstance = shim$1; -var didNotHydrateInstance = shim$1; -var didNotFindHydratableContainerInstance = shim$1; -var didNotFindHydratableContainerTextInstance = shim$1; -var didNotFindHydratableContainerSuspenseInstance = shim$1; -var didNotFindHydratableInstance = shim$1; -var didNotFindHydratableTextInstance = shim$1; -var didNotFindHydratableSuspenseInstance = shim$1; - -function _classCallCheck(instance, Constructor) { +function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -// Modules provided by RN: -var _nativeFabricUIManage = nativeFabricUIManager; -var createNode = _nativeFabricUIManage.createNode; -var cloneNode = _nativeFabricUIManage.cloneNode; -var cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren; -var cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps; -var cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps; -var createChildNodeSet = _nativeFabricUIManage.createChildSet; -var appendChildNode = _nativeFabricUIManage.appendChild; -var appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet; -var completeRoot = _nativeFabricUIManage.completeRoot; -var registerEventHandler = _nativeFabricUIManage.registerEventHandler; -var fabricMeasure = _nativeFabricUIManage.measure; -var fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow; -var 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. - -var nextReactTag = 2; +function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError( + "this hasn't been initialised - super() hasn't been called" + ); + } + return call && (typeof call === "object" || typeof call === "function") + ? call + : self; +} -// TODO: Remove this conditional once all changes have propagated. -if (registerEventHandler) { - /** - * Register the event emitter with the native bridge - */ - registerEventHandler(dispatchEvent); +function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError( + "Super expression must either be null or a function, not " + + typeof superClass + ); + } + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) + Object.setPrototypeOf + ? Object.setPrototypeOf(subClass, superClass) + : (subClass.__proto__ = superClass); } /** - * This is used for refs on host components. + * Class only exists for its Flow type. */ +var ReactNativeComponent = (function(_React$Component) { + _inherits(ReactNativeComponent, _React$Component); -var ReactFabricHostComponent = (function() { - function ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ) { - _classCallCheck(this, ReactFabricHostComponent); + function ReactNativeComponent() { + _classCallCheck$1(this, ReactNativeComponent); - this._nativeTag = tag; - this.viewConfig = viewConfig; - this.currentProps = props; - this._internalInstanceHandle = internalInstanceHandle; + return _possibleConstructorReturn( + this, + _React$Component.apply(this, arguments) + ); } - ReactFabricHostComponent.prototype.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); - }; + ReactNativeComponent.prototype.blur = function blur() {}; - ReactFabricHostComponent.prototype.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); - }; + ReactNativeComponent.prototype.focus = function focus() {}; - ReactFabricHostComponent.prototype.measure = function measure(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; + ReactNativeComponent.prototype.measure = function measure(callback) {}; - ReactFabricHostComponent.prototype.measureInWindow = function measureInWindow( + ReactNativeComponent.prototype.measureInWindow = function measureInWindow( callback - ) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; + ) {}; - ReactFabricHostComponent.prototype.measureLayout = function measureLayout( + ReactNativeComponent.prototype.measureLayout = function measureLayout( relativeToNativeNode, onSuccess, - onFail /* currently unused */ - ) { - if ( - typeof relativeToNativeNode === "number" || - !(relativeToNativeNode instanceof ReactFabricHostComponent) - ) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a ref to a native component." - ); + onFail + ) {}; + + ReactNativeComponent.prototype.setNativeProps = function setNativeProps( + nativeProps + ) {}; + + return ReactNativeComponent; +})(React.Component); + +/** + * This type keeps ReactNativeFiberHostComponent and NativeMethodsMixin in sync. + * It can also provide types for ReactNative applications that use NMM or refs. + */ +/** + * Flat ReactNative renderer bundles are too big for Flow to parse efficiently. + * Provide minimal Flow typing for the high-level RN API and call it a day. + */ + +var DiscreteEvent = 0; +var UserBlockingEvent = 1; +var ContinuousEvent = 2; + +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = warningWithoutStack$1; + +{ + warning = function(condition, format) { + if (condition) { return; } + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + // eslint-disable-next-line react-internal/warning-and-invariant-args - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; + for ( + var _len = arguments.length, + args = Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } - ReactFabricHostComponent.prototype.setNativeProps = function setNativeProps( - nativeProps - ) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" + warningWithoutStack$1.apply( + undefined, + [false, format + "%s"].concat(args, [stack]) ); - - return; }; - - return ReactFabricHostComponent; -})(); - -function appendInitialChild(parentInstance, child) { - appendChildNode(parentInstance.node, child.node); } -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = nextReactTag; - nextReactTag += 2; +var warning$1 = warning; - var viewConfig = getViewConfigForType(type); +// Intentionally not named imports because Rollup would use dynamic dispatch for +// CommonJS interop named imports. +var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var runWithPriority = Scheduler.unstable_runWithPriority; +var _nativeFabricUIManage$2 = nativeFabricUIManager; +var measureInWindow = _nativeFabricUIManage$2.measureInWindow; + +var activeTimeouts = new Map(); +var rootEventTypesToEventResponderInstances = new Map(); +var ownershipChangeListeners = new Set(); + +var globalOwner = null; + +var currentTimeStamp = 0; +var currentTimers = new Map(); +var currentInstance = null; +var currentEventQueue = null; +var currentEventQueuePriority = ContinuousEvent; +var currentTimerIDCounter = 0; + +var eventResponderContext = { + dispatchEvent: function(eventProp, eventValue, eventPriority) { + validateResponderContext(); + validateEventValue(eventValue); + if (eventPriority < currentEventQueuePriority) { + currentEventQueuePriority = eventPriority; + } + var responderInstance = currentInstance; + var target = responderInstance.fiber; + var responder = responderInstance.responder; + var listeners = collectListeners(eventProp, responder, target); + if (listeners.length !== 0) { + currentEventQueue.push(createEventQueueItem(eventValue, listeners)); + } + }, + isTargetWithinNode: function(childTarget, parentTarget) { + validateResponderContext(); + var childFiber = getFiberFromTarget(childTarget); + var parentFiber = getFiberFromTarget(parentTarget); - { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); + var node = childFiber; + while (node !== null) { + if (node === parentFiber) { + return true; } + node = node.return; } - } - - var updatePayload = create(props, viewConfig.validAttributes); + return false; + }, + getTargetBoundingRect: function(target, callback) { + measureInWindow(target.node, function(x, y, width, height) { + callback({ + left: x, + right: x + width, + top: y, + bottom: y + height + }); + }); + }, + addRootEventTypes: function(rootEventTypes) { + validateResponderContext(); + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + var eventResponderInstance = currentInstance; + registerRootEventType(rootEventType, eventResponderInstance); + } + }, + removeRootEventTypes: function(rootEventTypes) { + validateResponderContext(); + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; - var node = createNode( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload, // props - internalInstanceHandle // internalInstanceHandle - ); + var rootEventResponders = rootEventTypesToEventResponderInstances.get( + rootEventType + ); + var rootEventTypesSet = currentInstance.rootEventTypes; + if (rootEventTypesSet !== null) { + rootEventTypesSet.delete(rootEventType); + } + if (rootEventResponders !== undefined) { + rootEventResponders.delete(currentInstance); + } + } + }, + setTimeout: function(func, delay) { + validateResponderContext(); + if (currentTimers === null) { + currentTimers = new Map(); + } + var timeout = currentTimers.get(delay); + + var timerId = currentTimerIDCounter++; + if (timeout === undefined) { + var _timers = new Map(); + var _id = setTimeout(function() { + processTimers(_timers, delay); + }, delay); + timeout = { + id: _id, + timers: _timers + }; + currentTimers.set(delay, timeout); + } + timeout.timers.set(timerId, { + instance: currentInstance, + func: func, + id: timerId, + timeStamp: currentTimeStamp + }); + activeTimeouts.set(timerId, timeout); + return timerId; + }, + clearTimeout: function(timerId) { + validateResponderContext(); + var timeout = activeTimeouts.get(timerId); - var component = new ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ); + if (timeout !== undefined) { + var _timers2 = timeout.timers; + _timers2.delete(timerId); + if (_timers2.size === 0) { + clearTimeout(timeout.id); + } + } + }, + getTimeStamp: function() { + validateResponderContext(); + return currentTimeStamp; + } +}; +function createEventQueueItem(value, listeners) { return { - node: node, - canonical: component + value: value, + listeners: listeners }; } -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - (function() { - if (!hostContext.isInAParentText) { - throw ReactError( - "Text strings must be rendered within a component." +function validateEventValue(eventValue) { + if (typeof eventValue === "object" && eventValue !== null) { + var target = eventValue.target, + type = eventValue.type, + _timeStamp = eventValue.timeStamp; + + if (target == null || type == null || _timeStamp == null) { + throw new Error( + 'context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.' ); } - })(); + var showWarning = function(name) { + { + warning$1( + false, + "%s is not available on event objects created from event responder modules (React Flare). " + + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', + name, + name + ); + } + }; + eventValue.preventDefault = function() { + { + showWarning("preventDefault()"); + } + }; + eventValue.stopPropagation = function() { + { + showWarning("stopPropagation()"); + } + }; + eventValue.isDefaultPrevented = function() { + { + showWarning("isDefaultPrevented()"); + } + }; + eventValue.isPropagationStopped = function() { + { + showWarning("isPropagationStopped()"); + } + }; + // $FlowFixMe: we don't need value, Flow thinks we do + Object.defineProperty(eventValue, "nativeEvent", { + get: function() { + { + showWarning("nativeEvent"); + } + } + }); + } +} - var tag = nextReactTag; - nextReactTag += 2; +function getFiberFromTarget(target) { + if (target === null) { + return null; + } + return target.canonical._internalInstanceHandle || null; +} - var node = createNode( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { text: text }, // props - internalInstanceHandle // instance handle - ); +function processTimers(timers, delay) { + var timersArr = Array.from(timers.values()); + currentEventQueuePriority = ContinuousEvent; + try { + for (var i = 0; i < timersArr.length; i++) { + var _timersArr$i = timersArr[i], + _instance = _timersArr$i.instance, + _func = _timersArr$i.func, + _id2 = _timersArr$i.id, + _timeStamp2 = _timersArr$i.timeStamp; + + currentInstance = _instance; + currentEventQueue = []; + currentTimeStamp = _timeStamp2 + delay; + try { + _func(); + } finally { + activeTimeouts.delete(_id2); + } + } + processEventQueue(); + } finally { + currentTimers = null; + currentInstance = null; + currentEventQueue = null; + currentTimeStamp = 0; + } +} +function createFabricResponderEvent(topLevelType, nativeEvent, target) { return { - node: node + nativeEvent: nativeEvent, + responderTarget: target, + target: target, + type: topLevelType }; } -function finalizeInitialChildren( - parentInstance, - type, - props, - rootContainerInstance, - hostContext -) { - return false; +function validateResponderContext() { + (function() { + if (!(currentEventQueue && currentInstance)) { + throw ReactError( + Error( + "An event responder context was used outside of an event cycle. Use context.setTimeout() to use asynchronous responder context outside of event cycle ." + ) + ); + } + })(); } -function getRootHostContext(rootContainerInstance) { - return { isInAParentText: false }; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function processEventQueue() { + var eventQueue = currentEventQueue; + if (eventQueue.length === 0) { + return; + } + switch (currentEventQueuePriority) { + case DiscreteEvent: { + flushDiscreteUpdatesIfNeeded(currentTimeStamp); + discreteUpdates(function() { + batchedEventUpdates(processEvents, eventQueue); + }); + break; + } + case UserBlockingEvent: { + if (enableUserBlockingEvents) { + runWithPriority( + UserBlockingPriority, + batchedEventUpdates.bind(null, processEvents, eventQueue) + ); + } else { + batchedEventUpdates(processEvents, eventQueue); + } + break; + } + case ContinuousEvent: { + batchedEventUpdates(processEvents, eventQueue); + break; + } + } } -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; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function releaseOwnershipForEventResponderInstance(eventResponderInstance) { + if (globalOwner === eventResponderInstance) { + globalOwner = null; + triggerOwnershipListeners(); + return true; } + return false; } -function getChildHostContextForEventComponent(parentHostContext) { - // TODO: add getChildHostContextForEventComponent implementation - return parentHostContext; -} +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function collectListeners(eventProp, eventResponder, target) { + var eventListeners = []; + var node = target.return; + nodeTraversal: while (node !== null) { + switch (node.tag) { + case HostComponent: { + var dependencies = node.dependencies; -function getChildHostContextForEventTarget(parentHostContext, type) { - // TODO: add getChildHostContextForEventTarget implementation - return parentHostContext; -} + if (dependencies !== null) { + var respondersMap = dependencies.responders; -function getPublicInstance(instance) { - return instance.canonical; -} + if (respondersMap !== null && respondersMap.has(eventResponder)) { + break nodeTraversal; + } + } + break; + } + case FunctionComponent: + case MemoComponent: + case ForwardRef: { + var _dependencies = node.dependencies; -function prepareForCommit(containerInfo) { - // Noop -} + if (_dependencies !== null) { + var _listeners = _dependencies.listeners; -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. - instance.canonical.currentProps = newProps; - return updatePayload; -} - -function resetAfterCommit(containerInfo) { - // Noop -} - -function shouldDeprioritizeSubtree(type, props) { - return false; -} - -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 isPrimaryRenderer = false; - -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; - -// ------------------- -// Persistence -// ------------------- + if (_listeners !== null) { + for ( + var s = 0, listenersLength = _listeners.length; + s < listenersLength; + s++ + ) { + var listener = _listeners[s]; + var responder = listener.responder, + props = listener.props; -var supportsPersistence = true; + var listenerFunc = props[eventProp]; -function cloneInstance( - instance, - updatePayload, - type, - oldProps, - newProps, - internalInstanceHandle, - keepChildren, - recyclableInstance -) { - var node = instance.node; - var clone = void 0; - 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); + if ( + responder === eventResponder && + typeof listenerFunc === "function" + ) { + eventListeners.push(listenerFunc); + } + } + } + } + } } + node = node.return; } - 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); + return eventListeners; } -function appendChildToContainerChildSet(childSet, child) { - appendChildNodeToSet(childSet, child.node); -} +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function processEvents(eventQueue) { + for (var i = 0, length = eventQueue.length; i < length; i++) { + var _eventQueue$i = eventQueue[i], + _value = _eventQueue$i.value, + _listeners2 = _eventQueue$i.listeners; -function finalizeContainerChildren(container, newChildren) { - completeRoot(container, newChildren); + for (var s = 0, length2 = _listeners2.length; s < length2; s++) { + var listener = _listeners2[s]; + var type = + typeof _value === "object" && _value !== null ? _value.type : ""; + invokeGuardedCallbackAndCatchFirstError( + type, + listener, + undefined, + _value + ); + } + } } -function mountEventComponent(eventComponentInstance) { - throw new Error("Not yet implemented."); +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function responderEventTypesContainType(eventTypes, type) { + for (var i = 0, len = eventTypes.length; i < len; i++) { + if (eventTypes[i] === type) { + return true; + } + } + return false; } -function updateEventComponent(eventComponentInstance) { - throw new Error("Not yet implemented."); -} +function validateResponderTargetEventTypes(eventType, responder) { + var targetEventTypes = responder.targetEventTypes; + // Validate the target event type exists on the responder -function unmountEventComponent(eventComponentInstance) { - throw new Error("Not yet implemented."); + if (targetEventTypes !== null) { + return responderEventTypesContainType(targetEventTypes, eventType); + } + return false; } -function getEventTargetChildElement(type, props) { - throw new Error("Not yet implemented."); +function validateOwnership(responderInstance) { + return globalOwner === null || globalOwner === responderInstance; } -function handleEventTarget( - type, - props, - rootContainerInstance, - internalInstanceHandle +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function traverseAndHandleEventResponderInstances( + eventType, + targetFiber, + nativeEvent ) { - throw new Error("Not yet implemented."); -} + // Trigger event responders in this order: + // - Bubble target responder phase + // - Root responder phase -function commitEventTarget(type, props, instance, parentInstance) { - throw new Error("Not yet implemented."); -} - -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; + var responderEvent = createFabricResponderEvent( + eventType, + nativeEvent, + targetFiber !== null ? targetFiber.stateNode : null + ); + var visitedResponders = new Set(); + var node = targetFiber; + while (node !== null) { + var _node = node, + dependencies = _node.dependencies, + tag = _node.tag; + + if (tag === HostComponent && dependencies !== null) { + var respondersMap = dependencies.responders; + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + + if (validateOwnership(responderInstance)) { + var props = responderInstance.props, + responder = responderInstance.responder, + state = responderInstance.state, + target = responderInstance.target; -var describeComponentFrame = function(name, source, ownerName) { - var sourceInfo = ""; - 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; + if ( + !visitedResponders.has(responder) && + validateResponderTargetEventTypes(eventType, responder) + ) { + var onEvent = responder.onEvent; + visitedResponders.add(responder); + if (onEvent !== null) { + currentInstance = responderInstance; + responderEvent.responderTarget = target; + onEvent(responderEvent, eventResponderContext, props, state); + } + } } } } } - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; + node = node.return; } - return "\n in " + (name || "Unknown") + sourceInfo; -}; + // Root phase + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + eventType + ); + if (rootEventResponderInstances !== undefined) { + var _responderInstances = Array.from(rootEventResponderInstances); -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + for (var _i = 0; _i < _responderInstances.length; _i++) { + var _responderInstance = _responderInstances[_i]; + if (!validateOwnership(_responderInstance)) { + continue; + } + var _props = _responderInstance.props, + _responder = _responderInstance.responder, + _state = _responderInstance.state, + _target = _responderInstance.target; -function describeFiber(fiber) { - switch (fiber.tag) { - case HostRoot: - case HostPortal: - case HostText: - case Fragment: - case ContextProvider: - case ContextConsumer: - return ""; - default: - var owner = fiber._debugOwner; - var source = fiber._debugSource; - var name = getComponentName(fiber.type); - var ownerName = null; - if (owner) { - ownerName = getComponentName(owner.type); + var onRootEvent = _responder.onRootEvent; + if (onRootEvent !== null) { + currentInstance = _responderInstance; + responderEvent.responderTarget = _target; + onRootEvent(responderEvent, eventResponderContext, _props, _state); } - return describeComponentFrame(name, source, ownerName); + } } } -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - var node = workInProgress; - do { - info += describeFiber(node); - node = node.return; - } while (node); - return info; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function dispatchEventForResponderEventSystem( + topLevelType, + targetFiber, + nativeEvent +) { + var previousEventQueue = currentEventQueue; + var previousInstance = currentInstance; + var previousTimers = currentTimers; + var previousTimeStamp = currentTimeStamp; + var previousEventQueuePriority = currentEventQueuePriority; + currentTimers = null; + currentEventQueue = []; + currentEventQueuePriority = ContinuousEvent; + // We might want to control timeStamp another way here + currentTimeStamp = Date.now(); + try { + traverseAndHandleEventResponderInstances( + topLevelType, + targetFiber, + nativeEvent + ); + processEventQueue(); + } finally { + currentTimers = previousTimers; + currentInstance = previousInstance; + currentEventQueue = previousEventQueue; + currentTimeStamp = previousTimeStamp; + currentEventQueuePriority = previousEventQueuePriority; + } } -var current = null; -var phase = null; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function triggerOwnershipListeners() { + var listeningInstances = Array.from(ownershipChangeListeners); + var previousInstance = currentInstance; + var previousEventQueuePriority = currentEventQueuePriority; + var previousEventQueue = currentEventQueue; + try { + for (var i = 0; i < listeningInstances.length; i++) { + var _instance2 = listeningInstances[i]; + var props = _instance2.props, + responder = _instance2.responder, + state = _instance2.state; -function getCurrentFiberOwnerNameInDevOrNull() { - { - if (current === null) { - return null; - } - var owner = current._debugOwner; - if (owner !== null && typeof owner !== "undefined") { - return getComponentName(owner.type); + currentInstance = _instance2; + currentEventQueuePriority = ContinuousEvent; + currentEventQueue = []; + var onOwnershipChange = responder.onOwnershipChange; + if (onOwnershipChange !== null) { + onOwnershipChange(eventResponderContext, props, state); + } } + processEventQueue(); + } finally { + currentInstance = previousInstance; + currentEventQueue = previousEventQueue; + currentEventQueuePriority = previousEventQueuePriority; } - return null; } -function getCurrentFiberStackInDev() { - { - if (current === null) { - return ""; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function mountEventResponder(responder, responderInstance, props, state) { + if (responder.onOwnershipChange !== null) { + ownershipChangeListeners.add(responderInstance); + } + var onMount = responder.onMount; + if (onMount !== null) { + currentEventQueuePriority = ContinuousEvent; + currentInstance = responderInstance; + currentEventQueue = []; + try { + onMount(eventResponderContext, props, state); + processEventQueue(); + } finally { + currentEventQueue = null; + currentInstance = null; + currentTimers = null; } - // Safe because if current fiber exists, we are reconciling, - // and it is guaranteed to be the work-in-progress version. - return getStackByFiberInDevAndProd(current); } - return ""; } -function resetCurrentFiber() { - { - ReactDebugCurrentFrame.getCurrentStack = null; - current = null; - phase = null; +// TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic +function unmountEventResponder(responderInstance) { + var responder = responderInstance.responder; + var onUnmount = responder.onUnmount; + if (onUnmount !== null) { + var props = responderInstance.props, + state = responderInstance.state; + + currentEventQueue = []; + currentEventQueuePriority = ContinuousEvent; + currentInstance = responderInstance; + try { + onUnmount(eventResponderContext, props, state); + processEventQueue(); + } finally { + currentEventQueue = null; + currentInstance = null; + currentTimers = null; + } + } + releaseOwnershipForEventResponderInstance(responderInstance); + if (responder.onOwnershipChange !== null) { + ownershipChangeListeners.delete(responderInstance); + } + var rootEventTypesSet = responderInstance.rootEventTypes; + if (rootEventTypesSet !== null) { + var rootEventTypes = Array.from(rootEventTypesSet); + + for (var i = 0; i < rootEventTypes.length; i++) { + var topLevelEventType = rootEventTypes[i]; + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + topLevelEventType + ); + if (rootEventResponderInstances !== undefined) { + rootEventResponderInstances.delete(responderInstance); + } + } } } -function setCurrentFiber(fiber) { - { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; - current = fiber; - phase = null; +function registerRootEventType(rootEventType, responderInstance) { + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + rootEventType + ); + if (rootEventResponderInstances === undefined) { + rootEventResponderInstances = new Set(); + rootEventTypesToEventResponderInstances.set( + rootEventType, + rootEventResponderInstances + ); + } + var rootEventTypesSet = responderInstance.rootEventTypes; + if (rootEventTypesSet === null) { + rootEventTypesSet = responderInstance.rootEventTypes = new Set(); } + (function() { + if (!!rootEventTypesSet.has(rootEventType)) { + throw ReactError( + Error( + 'addRootEventTypes() found a duplicate root event type of "' + + rootEventType + + '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.' + ) + ); + } + })(); + rootEventTypesSet.add(rootEventType); + rootEventResponderInstances.add(responderInstance); } -function setCurrentPhase(lifeCyclePhase) { - { - phase = lifeCyclePhase; +function addRootEventTypesForResponderInstance( + responderInstance, + rootEventTypes +) { + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + registerRootEventType(rootEventType, responderInstance); } } -// Prefix measurements so that it's possible to filter them. -// Longer prefixes are hard to read in DevTools. -var reactEmoji = "\u269B"; -var warningEmoji = "\u26D4"; +function dispatchEvent(target, topLevelType, nativeEvent) { + var targetFiber = target; + if (enableFlareAPI) { + // React Flare event system + dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent); + } + batchedUpdates(function() { + // Heritage plugin event system + runExtractedPluginEventsInBatch( + topLevelType, + targetFiber, + nativeEvent, + nativeEvent.target + ); + }); + // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. +} + +// Renderers that don't support mutation +// can re-export everything from this module. + +function shim() { + (function() { + { + throw ReactError( + 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) +var supportsMutation = false; +var appendChild = shim; +var appendChildToContainer = shim; +var commitTextUpdate = shim; +var commitMount = shim; +var commitUpdate = shim; +var insertBefore = shim; +var insertInContainerBefore = shim; +var removeChild = shim; +var removeChildFromContainer = shim; +var resetTextContent = shim; +var hideInstance = shim; +var hideTextInstance = shim; +var unhideInstance = shim; +var unhideTextInstance = shim; + +// Renderers that don't support hydration +// can re-export everything from this module. + +function shim$1() { + (function() { + { + throw ReactError( + 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 supportsHydration = false; +var canHydrateInstance = shim$1; +var canHydrateTextInstance = shim$1; +var canHydrateSuspenseInstance = shim$1; +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var registerSuspenseInstanceRetry = shim$1; +var getNextHydratableSibling = shim$1; +var getFirstHydratableChild = shim$1; +var hydrateInstance = shim$1; +var hydrateTextInstance = shim$1; +var getNextHydratableInstanceAfterSuspenseInstance = shim$1; +var clearSuspenseBoundary = shim$1; +var clearSuspenseBoundaryFromContainer = shim$1; +var didNotMatchHydratedContainerTextInstance = shim$1; +var didNotMatchHydratedTextInstance = shim$1; +var didNotHydrateContainerInstance = shim$1; +var didNotHydrateInstance = shim$1; +var didNotFindHydratableContainerInstance = shim$1; +var didNotFindHydratableContainerTextInstance = shim$1; +var didNotFindHydratableContainerSuspenseInstance = shim$1; +var didNotFindHydratableInstance = shim$1; +var didNotFindHydratableTextInstance = shim$1; +var didNotFindHydratableSuspenseInstance = shim$1; + +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +} + +// Modules provided by RN: +var _nativeFabricUIManage$1 = nativeFabricUIManager; +var createNode = _nativeFabricUIManage$1.createNode; +var cloneNode = _nativeFabricUIManage$1.cloneNode; +var cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren; +var cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps; +var cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps; +var createChildNodeSet = _nativeFabricUIManage$1.createChildSet; +var appendChildNode = _nativeFabricUIManage$1.appendChild; +var appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet; +var completeRoot = _nativeFabricUIManage$1.completeRoot; +var registerEventHandler = _nativeFabricUIManage$1.registerEventHandler; +var fabricMeasure = _nativeFabricUIManage$1.measure; +var fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow; +var fabricMeasureLayout = _nativeFabricUIManage$1.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. + +var nextReactTag = 2; + +// 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. + */ + +var ReactFabricHostComponent = (function() { + function ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle + ) { + _classCallCheck(this, ReactFabricHostComponent); + + this._nativeTag = tag; + this.viewConfig = viewConfig; + this.currentProps = props; + this._internalInstanceHandle = internalInstanceHandle; + } + + ReactFabricHostComponent.prototype.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + }; + + ReactFabricHostComponent.prototype.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + }; + + ReactFabricHostComponent.prototype.measure = function measure(callback) { + fabricMeasure( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + + ReactFabricHostComponent.prototype.measureInWindow = function measureInWindow( + callback + ) { + fabricMeasureInWindow( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + + ReactFabricHostComponent.prototype.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail /* currently unused */ + ) { + if ( + typeof relativeToNativeNode === "number" || + !(relativeToNativeNode instanceof ReactFabricHostComponent) + ) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + + return; + } + + fabricMeasureLayout( + this._internalInstanceHandle.stateNode.node, + relativeToNativeNode._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + + ReactFabricHostComponent.prototype.setNativeProps = function setNativeProps( + nativeProps + ) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + + return; + }; + + return ReactFabricHostComponent; +})(); + +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 +) { + (function() { + if (!hostContext.isInAParentText) { + throw ReactError( + 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 finalizeInitialChildren( + parentInstance, + type, + props, + rootContainerInstance, + hostContext +) { + 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"; + + if (prevIsInAParentText !== isInAParentText) { + return { isInAParentText: isInAParentText }; + } else { + return parentHostContext; + } +} + +function getPublicInstance(instance) { + return instance.canonical; +} + +function prepareForCommit(containerInfo) { + // Noop +} + +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. + instance.canonical.currentProps = newProps; + return updatePayload; +} + +function resetAfterCommit(containerInfo) { + // Noop +} + +function shouldDeprioritizeSubtree(type, props) { + return false; +} + +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 isPrimaryRenderer = false; + +// The Fabric renderer shouldn't trigger missing act() warnings +var warnsIfNotActing = false; + +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; + +// ------------------- +// Persistence +// ------------------- + +var supportsPersistence = true; + +function cloneInstance( + instance, + updatePayload, + type, + oldProps, + newProps, + internalInstanceHandle, + keepChildren, + recyclableInstance +) { + var node = instance.node; + var clone = void 0; + 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 mountResponderInstance( + responder, + responderInstance, + props, + state, + instance, + rootContainerInstance +) { + if (enableFlareAPI) { + var rootEventTypes = responder.rootEventTypes; + + if (rootEventTypes !== null) { + addRootEventTypesForResponderInstance(responderInstance, rootEventTypes); + } + mountEventResponder(responder, responderInstance, props, state); + } +} + +function unmountResponderInstance(responderInstance) { + if (enableFlareAPI) { + // TODO stop listening to targetEventTypes + unmountEventResponder(responderInstance); + } +} + +function getFundamentalComponentInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function mountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function shouldUpdateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function updateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function unmountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function cloneFundamentalInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; + +var describeComponentFrame = function(name, source, ownerName) { + var sourceInfo = ""; + 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 + ")"; + } + return "\n in " + (name || "Unknown") + sourceInfo; +}; + +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + +function describeFiber(fiber) { + switch (fiber.tag) { + case HostRoot: + case HostPortal: + case HostText: + case Fragment: + case ContextProvider: + case ContextConsumer: + return ""; + default: + var owner = fiber._debugOwner; + var source = fiber._debugSource; + var name = getComponentName(fiber.type); + var ownerName = null; + if (owner) { + ownerName = getComponentName(owner.type); + } + return describeComponentFrame(name, source, ownerName); + } +} + +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + var node = workInProgress; + do { + info += describeFiber(node); + node = node.return; + } while (node); + return info; +} + +var current = null; +var phase = null; + +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } + var owner = current._debugOwner; + if (owner !== null && typeof owner !== "undefined") { + return getComponentName(owner.type); + } + } + return null; +} + +function getCurrentFiberStackInDev() { + { + if (current === null) { + return ""; + } + // Safe because if current fiber exists, we are reconciling, + // and it is guaranteed to be the work-in-progress version. + return getStackByFiberInDevAndProd(current); + } + return ""; +} + +function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + phase = null; + } +} + +function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; + current = fiber; + phase = null; + } +} + +function setCurrentPhase(lifeCyclePhase) { + { + phase = lifeCyclePhase; + } +} + +// Prefix measurements so that it's possible to filter them. +// Longer prefixes are hard to read in DevTools. +var reactEmoji = "\u269B"; +var warningEmoji = "\u26D4"; var supportsUserTiming = typeof performance !== "undefined" && typeof performance.mark === "function" && @@ -4853,7 +5731,9 @@ function pushTopLevelContextObject(fiber, context, didChange) { (function() { if (!(contextStackCursor.current === emptyContextObject)) { throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -4901,10 +5781,12 @@ function processChildContext(fiber, type, parentContext) { (function() { if (!(contextKey in childContextTypes)) { throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); } })(); @@ -4955,7 +5837,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { (function() { if (!instance) { throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -4982,162 +5866,50 @@ function invalidateContextProvider(workInProgress, type, didChange) { pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -} - -function findCurrentUnmaskedContext(fiber) { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - (function() { - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw ReactError( - "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); - (function() { - { - throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); -} - -var onCommitFiberRoot = null; -var onCommitFiberUnmount = null; -var hasLoggedError = false; - -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); - } - } - }; -} - -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; - -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; - } - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - 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) { - { - warningWithoutStack$1( - false, - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://fb.me/react-devtools" - ); - } - // DevTools exists, even though it doesn't support Fiber. - return true; - } - try { - var rendererID = hook.inject(internals); - // We have successfully injected, so now it is safe to set up hooks. - onCommitFiberRoot = catchErrors(function(root) { - var didError = (root.current.effectTag & DidCapture) === DidCapture; - hook.onCommitFiberRoot(rendererID, root, undefined, didError); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); - } - } - // DevTools exists - return true; -} - -function onCommitRoot(root) { - if (typeof onCommitFiberRoot === "function") { - onCommitFiberRoot(root); - } -} - -function onCommitUnmount(fiber) { - if (typeof onCommitFiberUnmount === "function") { - onCommitFiberUnmount(fiber); - } -} - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = warningWithoutStack$1; +} -{ - warning = function(condition, format) { - if (condition) { - return; +function findCurrentUnmaskedContext(fiber) { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + (function() { + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw ReactError( + 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 ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); - // eslint-disable-next-line react-internal/warning-and-invariant-args + })(); - for ( - var _len = arguments.length, - args = Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; + 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; + } } - - warningWithoutStack$1.apply( - undefined, - [false, format + "%s"].concat(args, [stack]) - ); - }; + node = node.return; + } while (node !== null); + (function() { + { + throw ReactError( + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) + ); + } + })(); } -var warning$1 = warning; +var LegacyRoot = 0; +var BatchedRoot = 1; +var ConcurrentRoot = 2; // Intentionally not named imports because Rollup would use dynamic dispatch for // CommonJS interop named imports. @@ -5145,6 +5917,7 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority; var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback; var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback; var Scheduler_shouldYield = Scheduler.unstable_shouldYield; +var Scheduler_requestPaint = Scheduler.unstable_requestPaint; var Scheduler_now = Scheduler.unstable_now; var Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel; @@ -5166,7 +5939,9 @@ if (enableSchedulerTracing) { ) ) { throw ReactError( - "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 http://fb.me/react-profiling" + 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 http://fb.me/react-profiling" + ) ); } })(); @@ -5178,21 +5953,20 @@ var fakeCallbackNode = {}; // 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 UserBlockingPriority$1 = 98; var NormalPriority = 97; var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. -var shouldYield = disableYielding - ? function() { - return false; - } // Never yield when `disableYielding` is on - : Scheduler_shouldYield; +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 immediateQueue = null; +var syncQueue = null; var immediateQueueCallbackNode = null; -var isFlushingImmediate = false; +var isFlushingSyncQueue = false; var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. @@ -5214,7 +5988,7 @@ function getCurrentPriorityLevel() { case Scheduler_ImmediatePriority: return ImmediatePriority; case Scheduler_UserBlockingPriority: - return UserBlockingPriority; + return UserBlockingPriority$1; case Scheduler_NormalPriority: return NormalPriority; case Scheduler_LowPriority: @@ -5224,7 +5998,7 @@ function getCurrentPriorityLevel() { default: (function() { { - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } })(); } @@ -5234,7 +6008,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { switch (reactPriorityLevel) { case ImmediatePriority: return Scheduler_ImmediatePriority; - case UserBlockingPriority: + case UserBlockingPriority$1: return Scheduler_UserBlockingPriority; case NormalPriority: return Scheduler_NormalPriority; @@ -5245,88 +6019,94 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { default: (function() { { - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } })(); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(priorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (reactPriorityLevel === ImmediatePriority) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushImmediateQueue`. - if (immediateQueue === null) { - immediateQueue = [callback]; - // Flush the queue in the next tick, at the earliest. - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ); - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - immediateQueue.push(callback); - } - return fakeCallbackNode; - } - // Otherwise pass through to Scheduler. 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 flushImmediateQueue() { +function flushSyncCallbackQueue() { if (immediateQueueCallbackNode !== null) { Scheduler_cancelCallback(immediateQueueCallbackNode); } - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && immediateQueue !== null) { +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. - isFlushingImmediate = true; + isFlushingSyncQueue = true; var i = 0; try { var _isSync = true; - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do { - callback = callback(_isSync); - } while (callback !== null); - } - immediateQueue = null; + var queue = syncQueue; + runWithPriority$1(ImmediatePriority, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do { + callback = callback(_isSync); + } while (callback !== null); + } + }); + syncQueue = null; } catch (error) { // If something throws, leave the remaining callbacks on the queue. - if (immediateQueue !== null) { - immediateQueue = immediateQueue.slice(i + 1); + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); } // Resume flushing in the next tick Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ); throw error; } finally { - isFlushingImmediate = false; + isFlushingSyncQueue = false; } } } -var NoContext = 0; -var ConcurrentMode = 1; -var StrictMode = 2; -var ProfileMode = 4; +var NoMode = 0; +var StrictMode = 1; +// TODO: Remove BatchedMode and ConcurrentMode by reading from the root +// tag instead +var BatchedMode = 2; +var ConcurrentMode = 4; +var ProfileMode = 8; // Max 31 bit integer. The max integer size in V8 for 32-bit systems. // Math.pow(2, 30) - 1 @@ -5336,9 +6116,10 @@ var MAX_SIGNED_31_BIT_INT = 1073741823; var NoWork = 0; var Never = 1; var Sync = MAX_SIGNED_31_BIT_INT; +var Batched = Sync - 1; var UNIT_SIZE = 10; -var MAGIC_NUMBER_OFFSET = MAX_SIGNED_31_BIT_INT - 1; +var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms. function msToExpirationTime(ms) { @@ -5377,10 +6158,13 @@ function computeAsyncExpiration(currentTime) { ); } -// Same as computeAsyncExpiration but without the bucketing logic. This is -// used to compute timestamps instead of actual expiration times. -function computeAsyncExpirationNoBucket(currentTime) { - return currentTime - LOW_PRIORITY_EXPIRATION / UNIT_SIZE; +function computeSuspenseExpiration(currentTime, timeoutMs) { + // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time? + return computeExpirationBucket( + currentTime, + timeoutMs, + LOW_PRIORITY_BATCH_SIZE + ); } // We intentionally set a higher expiration time for interactive updates in @@ -5418,7 +6202,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return ImmediatePriority; } if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) { - return UserBlockingPriority; + return UserBlockingPriority$1; } if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) { return NormalPriority; @@ -5552,332 +6336,754 @@ var lowPriorityWarning = function() {}; var lowPriorityWarning$1 = lowPriorityWarning; var ReactStrictModeWarnings = { - discardPendingWarnings: function() {}, - flushPendingDeprecationWarnings: function() {}, - flushPendingUnsafeLifecycleWarnings: function() {}, - recordDeprecationWarnings: function(fiber, instance) {}, recordUnsafeLifecycleWarnings: function(fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function() {}, recordLegacyContextWarning: function(fiber, instance) {}, - flushLegacyContextWarning: function() {} + flushLegacyContextWarning: function() {}, + discardPendingWarnings: function() {} }; { - var LIFECYCLE_SUGGESTIONS = { - UNSAFE_componentWillMount: "componentDidMount", - UNSAFE_componentWillReceiveProps: "static getDerivedStateFromProps", - UNSAFE_componentWillUpdate: "componentDidUpdate" + var findStrictRoot = function(fiber) { + var maybeStrictRoot = null; + + var node = fiber; + while (node !== null) { + if (node.mode & StrictMode) { + maybeStrictRoot = node; + } + node = node.return; + } + + return maybeStrictRoot; + }; + + var setToSortedString = function(set) { + var array = []; + set.forEach(function(value) { + array.push(value); + }); + return array.sort().join(", "); + }; + + var pendingComponentWillMountWarnings = []; + var pendingUNSAFE_ComponentWillMountWarnings = []; + var pendingComponentWillReceivePropsWarnings = []; + var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + var pendingComponentWillUpdateWarnings = []; + var pendingUNSAFE_ComponentWillUpdateWarnings = []; + + // Tracks components we have already warned about. + var didWarnAboutUnsafeLifecycles = new Set(); + + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( + fiber, + instance + ) { + // Dedup strategy: Warn once per component. + if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { + return; + } + + if ( + typeof instance.componentWillMount === "function" && + // Don't warn about react-lifecycles-compat polyfilled components. + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + pendingComponentWillMountWarnings.push(fiber); + } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillMount === "function" + ) { + pendingUNSAFE_ComponentWillMountWarnings.push(fiber); + } + + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== true + ) { + pendingComponentWillReceivePropsWarnings.push(fiber); + } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); + } + + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + pendingComponentWillUpdateWarnings.push(fiber); + } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); + } + }; + + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { + // We do an initial pass to gather component names + var componentWillMountUniqueNames = new Set(); + if (pendingComponentWillMountWarnings.length > 0) { + pendingComponentWillMountWarnings.forEach(function(fiber) { + componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillMountWarnings = []; + } + + var UNSAFE_componentWillMountUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { + pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { + UNSAFE_componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillMountWarnings = []; + } + + var componentWillReceivePropsUniqueNames = new Set(); + if (pendingComponentWillReceivePropsWarnings.length > 0) { + pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { + componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingComponentWillReceivePropsWarnings = []; + } + + var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { + UNSAFE_componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + } + + var componentWillUpdateUniqueNames = new Set(); + if (pendingComponentWillUpdateWarnings.length > 0) { + pendingComponentWillUpdateWarnings.forEach(function(fiber) { + componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingComponentWillUpdateWarnings = []; + } + + var UNSAFE_componentWillUpdateUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { + pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { + UNSAFE_componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingUNSAFE_ComponentWillUpdateWarnings = []; + } + + // Finally, we flush all the warnings + // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' + if (UNSAFE_componentWillMountUniqueNames.size > 0) { + var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "\nPlease update the following components: %s", + sortedNames + ); + } + + if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames = setToSortedString( + UNSAFE_componentWillReceivePropsUniqueNames + ); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, " + + "refactor your code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" + + "\nPlease update the following components: %s", + _sortedNames + ); + } + + if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { + var _sortedNames2 = setToSortedString( + UNSAFE_componentWillUpdateUniqueNames + ); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "\nPlease update the following components: %s", + _sortedNames2 + ); + } + + if (componentWillMountUniqueNames.size > 0) { + var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); + + lowPriorityWarning$1( + false, + "componentWillMount has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames3 + ); + } + + if (componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames4 = setToSortedString( + componentWillReceivePropsUniqueNames + ); + + lowPriorityWarning$1( + false, + "componentWillReceiveProps has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, refactor your " + + "code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" + + "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames4 + ); + } + + if (componentWillUpdateUniqueNames.size > 0) { + var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); + + lowPriorityWarning$1( + false, + "componentWillUpdate has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames5 + ); + } + }; + + var pendingLegacyContextWarning = new Map(); + + // Tracks components we have already warned about. + var didWarnAboutLegacyContext = new Set(); + + ReactStrictModeWarnings.recordLegacyContextWarning = function( + fiber, + instance + ) { + var strictRoot = findStrictRoot(fiber); + if (strictRoot === null) { + warningWithoutStack$1( + false, + "Expected to find a StrictMode component in a strict mode tree. " + + "This error is likely caused by a bug in React. Please file an issue." + ); + return; + } + + // Dedup strategy: Warn once per component. + if (didWarnAboutLegacyContext.has(fiber.type)) { + return; + } + + var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); + + if ( + fiber.type.contextTypes != null || + fiber.type.childContextTypes != null || + (instance !== null && typeof instance.getChildContext === "function") + ) { + if (warningsForRoot === undefined) { + warningsForRoot = []; + pendingLegacyContextWarning.set(strictRoot, warningsForRoot); + } + warningsForRoot.push(fiber); + } }; - var pendingComponentWillMountWarnings = []; - var pendingComponentWillReceivePropsWarnings = []; - var pendingComponentWillUpdateWarnings = []; - var pendingUnsafeLifecycleWarnings = new Map(); - var pendingLegacyContextWarning = new Map(); + ReactStrictModeWarnings.flushLegacyContextWarning = function() { + pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { + var uniqueNames = new Set(); + fiberArray.forEach(function(fiber) { + uniqueNames.add(getComponentName(fiber.type) || "Component"); + didWarnAboutLegacyContext.add(fiber.type); + }); - // Tracks components we have already warned about. - var didWarnAboutDeprecatedLifecycles = new Set(); - var didWarnAboutUnsafeLifecycles = new Set(); - var didWarnAboutLegacyContext = new Set(); + var sortedNames = setToSortedString(uniqueNames); + var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - var setToSortedString = function(set) { - var array = []; - set.forEach(function(value) { - array.push(value); + warningWithoutStack$1( + false, + "Legacy context API has been detected within a strict-mode tree: %s" + + "\n\nThe old API will be supported in all 16.x releases, but applications " + + "using it should migrate to the new version." + + "\n\nPlease update the following components: %s" + + "\n\nLearn more about this warning here:" + + "\nhttps://fb.me/react-legacy-context", + strictRootComponentStack, + sortedNames + ); }); - return array.sort().join(", "); }; ReactStrictModeWarnings.discardPendingWarnings = function() { pendingComponentWillMountWarnings = []; + pendingUNSAFE_ComponentWillMountWarnings = []; pendingComponentWillReceivePropsWarnings = []; + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; pendingComponentWillUpdateWarnings = []; - pendingUnsafeLifecycleWarnings = new Map(); + pendingUNSAFE_ComponentWillUpdateWarnings = []; pendingLegacyContextWarning = new Map(); }; +} - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { - pendingUnsafeLifecycleWarnings.forEach(function( - lifecycleWarningsMap, - strictRoot - ) { - var lifecyclesWarningMessages = []; - - Object.keys(lifecycleWarningsMap).forEach(function(lifecycle) { - var lifecycleWarnings = lifecycleWarningsMap[lifecycle]; - if (lifecycleWarnings.length > 0) { - var componentNames = new Set(); - lifecycleWarnings.forEach(function(fiber) { - componentNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - - var formatted = lifecycle.replace("UNSAFE_", ""); - var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle]; - var sortedComponentNames = setToSortedString(componentNames); - - lifecyclesWarningMessages.push( - formatted + - ": Please update the following components to use " + - (suggestion + " instead: " + sortedComponentNames) - ); - } - }); +// Resolves type to a family. - if (lifecyclesWarningMessages.length > 0) { - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); +// Used by React Refresh runtime through DevTools Global Hook. - warningWithoutStack$1( - false, - "Unsafe lifecycle methods were found within a strict-mode tree:%s" + - "\n\n%s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-strict-mode-warnings", - strictRootComponentStack, - lifecyclesWarningMessages.join("\n\n") - ); - } - }); +var resolveFamily = null; +// $FlowFixMe Flow gets confused by a WeakSet feature check below. +var failedBoundaries = null; - pendingUnsafeLifecycleWarnings = new Map(); - }; +var setRefreshHandler = function(handler) { + { + resolveFamily = handler; + } +}; - var findStrictRoot = function(fiber) { - var maybeStrictRoot = null; +function resolveFunctionForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + var family = resolveFamily(type); + if (family === undefined) { + return type; + } + // Use the latest known implementation. + return family.current; + } +} - var node = fiber; - while (node !== null) { - if (node.mode & StrictMode) { - maybeStrictRoot = node; +function resolveClassForHotReloading(type) { + // No implementation differences. + return resolveFunctionForHotReloading(type); +} + +function resolveForwardRefForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + var family = resolveFamily(type); + if (family === undefined) { + // Check if we're dealing with a real forwardRef. Don't want to crash early. + if ( + type !== null && + type !== undefined && + typeof type.render === "function" + ) { + // ForwardRef is special because its resolved .type is an object, + // but it's possible that we only have its inner render function in the map. + // If that inner render function is different, we'll build a new forwardRef type. + var currentRender = resolveFunctionForHotReloading(type.render); + if (type.render !== currentRender) { + var syntheticType = { + $$typeof: REACT_FORWARD_REF_TYPE, + render: currentRender + }; + if (type.displayName !== undefined) { + syntheticType.displayName = type.displayName; + } + return syntheticType; + } } - node = node.return; + return type; } + // Use the latest known implementation. + return family.current; + } +} - return maybeStrictRoot; - }; +function isCompatibleFamilyForHotReloading(fiber, element) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return false; + } - ReactStrictModeWarnings.flushPendingDeprecationWarnings = function() { - if (pendingComponentWillMountWarnings.length > 0) { - var uniqueNames = new Set(); - pendingComponentWillMountWarnings.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); + var prevType = fiber.elementType; + var nextType = element.type; - var sortedNames = setToSortedString(uniqueNames); + // If we got here, we know types aren't === equal. + var needsCompareFamilies = false; - lowPriorityWarning$1( - false, - "componentWillMount is deprecated and will be removed in the next major version. " + - "Use componentDidMount instead. As a temporary workaround, " + - "you can rename to UNSAFE_componentWillMount." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - sortedNames - ); + var $$typeofNextType = + typeof nextType === "object" && nextType !== null + ? nextType.$$typeof + : null; - pendingComponentWillMountWarnings = []; + switch (fiber.tag) { + case ClassComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } + break; + } + case FunctionComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + // We don't know the inner type yet. + // We're going to assume that the lazy inner type is stable, + // and so it is sufficient to avoid reconciling it away. + // We're not going to unwrap or actually use the new lazy type. + needsCompareFamilies = true; + } + break; + } + case ForwardRef: { + if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + break; + } + case MemoComponent: + case SimpleMemoComponent: { + if ($$typeofNextType === REACT_MEMO_TYPE) { + // TODO: if it was but can no longer be simple, + // we shouldn't set this. + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + break; + } + default: + return false; } - if (pendingComponentWillReceivePropsWarnings.length > 0) { - var _uniqueNames = new Set(); - pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { - _uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); - - var _sortedNames = setToSortedString(_uniqueNames); + // Check if both types have a family and it's the same one. + if (needsCompareFamilies) { + // Note: memo() and forwardRef() we'll compare outer rather than inner type. + // This means both of them need to be registered to preserve state. + // If we unwrapped and compared the inner types for wrappers instead, + // then we would risk falsely saying two separate memo(Foo) + // calls are equivalent because they wrap the same Foo function. + var prevFamily = resolveFamily(prevType); + if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { + return true; + } + } + return false; + } +} - lowPriorityWarning$1( - false, - "componentWillReceiveProps is deprecated and will be removed in the next major version. " + - "Use static getDerivedStateFromProps instead." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - _sortedNames - ); +function markFailedErrorBoundaryForHotReloading(fiber) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + if (typeof WeakSet !== "function") { + return; + } + if (failedBoundaries === null) { + failedBoundaries = new WeakSet(); + } + failedBoundaries.add(fiber); + } +} - pendingComponentWillReceivePropsWarnings = []; +var scheduleRefresh = function(root, update) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; } + var _staleFamilies = update.staleFamilies, + _updatedFamilies = update.updatedFamilies; - if (pendingComponentWillUpdateWarnings.length > 0) { - var _uniqueNames2 = new Set(); - pendingComponentWillUpdateWarnings.forEach(function(fiber) { - _uniqueNames2.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); + flushPassiveEffects(); + flushSync(function() { + scheduleFibersWithFamiliesRecursively( + root.current, + _updatedFamilies, + _staleFamilies + ); + }); + } +}; + +var scheduleRoot = function(root, element) { + { + if (root.context !== emptyContextObject) { + // Super edge case: root has a legacy _renderSubtree context + // but we don't know the parentComponent so we can't pass it. + // Just ignore. We'll delete this with _renderSubtree code path later. + return; + } + flushPassiveEffects(); + updateContainerAtExpirationTime(element, root, null, Sync, null); + } +}; - var _sortedNames2 = setToSortedString(_uniqueNames2); +function scheduleFibersWithFamiliesRecursively( + fiber, + updatedFamilies, + staleFamilies +) { + { + var alternate = fiber.alternate, + child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; - lowPriorityWarning$1( - false, - "componentWillUpdate is deprecated and will be removed in the next major version. " + - "Use componentDidUpdate instead. As a temporary workaround, " + - "you can rename to UNSAFE_componentWillUpdate." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - _sortedNames2 - ); + var candidateType = null; + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + default: + break; + } - pendingComponentWillUpdateWarnings = []; + if (resolveFamily === null) { + throw new Error("Expected resolveFamily to be set during hot reload."); } - }; - ReactStrictModeWarnings.recordDeprecationWarnings = function( - fiber, - instance - ) { - // Dedup strategy: Warn once per component. - if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) { - return; + var needsRender = false; + var needsRemount = false; + if (candidateType !== null) { + var family = resolveFamily(candidateType); + if (family !== undefined) { + if (staleFamilies.has(family)) { + needsRemount = true; + } else if (updatedFamilies.has(family)) { + needsRender = true; + } + } + } + if (failedBoundaries !== null) { + if ( + failedBoundaries.has(fiber) || + (alternate !== null && failedBoundaries.has(alternate)) + ) { + needsRemount = true; + } } - // Don't warn about react-lifecycles-compat polyfilled components. - if ( - typeof instance.componentWillMount === "function" && - instance.componentWillMount.__suppressDeprecationWarning !== true - ) { - pendingComponentWillMountWarnings.push(fiber); + if (needsRemount) { + fiber._debugNeedsRemount = true; } - if ( - typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== true - ) { - pendingComponentWillReceivePropsWarnings.push(fiber); + if (needsRemount || needsRender) { + scheduleWork(fiber, Sync); } - if ( - typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true - ) { - pendingComponentWillUpdateWarnings.push(fiber); + if (child !== null && !needsRemount) { + scheduleFibersWithFamiliesRecursively( + child, + updatedFamilies, + staleFamilies + ); } - }; - - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( - fiber, - instance - ) { - var strictRoot = findStrictRoot(fiber); - if (strictRoot === null) { - warningWithoutStack$1( - false, - "Expected to find a StrictMode component in a strict mode tree. " + - "This error is likely caused by a bug in React. Please file an issue." + if (sibling !== null) { + scheduleFibersWithFamiliesRecursively( + sibling, + updatedFamilies, + staleFamilies ); - return; } + } +} - // Dedup strategy: Warn once per component. - // This is difficult to track any other way since component names - // are often vague and are likely to collide between 3rd party libraries. - // An expand property is probably okay to use here since it's DEV-only, - // and will only be set in the event of serious warnings. - if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { - return; - } +var findHostInstancesForRefresh = function(root, families) { + { + var hostInstances = new Set(); + var types = new Set( + families.map(function(family) { + return family.current; + }) + ); + findHostInstancesForMatchingFibersRecursively( + root.current, + types, + hostInstances + ); + return hostInstances; + } +}; - var warningsForRoot = void 0; - if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) { - warningsForRoot = { - UNSAFE_componentWillMount: [], - UNSAFE_componentWillReceiveProps: [], - UNSAFE_componentWillUpdate: [] - }; +function findHostInstancesForMatchingFibersRecursively( + fiber, + types, + hostInstances +) { + { + var child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; - pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot); - } else { - warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot); + var candidateType = null; + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + default: + break; } - var unsafeLifecycles = []; - if ( - (typeof instance.componentWillMount === "function" && - instance.componentWillMount.__suppressDeprecationWarning !== true) || - typeof instance.UNSAFE_componentWillMount === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillMount"); - } - if ( - (typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== - true) || - typeof instance.UNSAFE_componentWillReceiveProps === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillReceiveProps"); - } - if ( - (typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true) || - typeof instance.UNSAFE_componentWillUpdate === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillUpdate"); + var didMatch = false; + if (candidateType !== null) { + if (types.has(candidateType)) { + didMatch = true; + } } - if (unsafeLifecycles.length > 0) { - unsafeLifecycles.forEach(function(lifecycle) { - warningsForRoot[lifecycle].push(fiber); - }); + if (didMatch) { + // We have a match. This only drills down to the closest host components. + // There's no need to search deeper because for the purpose of giving + // visual feedback, "flashing" outermost parent rectangles is sufficient. + findHostInstancesForFiberShallowly(fiber, hostInstances); + } else { + // If there's no match, maybe there will be one further down in the child tree. + if (child !== null) { + findHostInstancesForMatchingFibersRecursively( + child, + types, + hostInstances + ); + } } - }; - ReactStrictModeWarnings.recordLegacyContextWarning = function( - fiber, - instance - ) { - var strictRoot = findStrictRoot(fiber); - if (strictRoot === null) { - warningWithoutStack$1( - false, - "Expected to find a StrictMode component in a strict mode tree. " + - "This error is likely caused by a bug in React. Please file an issue." + if (sibling !== null) { + findHostInstancesForMatchingFibersRecursively( + sibling, + types, + hostInstances ); - return; } + } +} - // Dedup strategy: Warn once per component. - if (didWarnAboutLegacyContext.has(fiber.type)) { +function findHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var foundHostInstances = findChildHostInstancesForFiberShallowly( + fiber, + hostInstances + ); + if (foundHostInstances) { return; } + // If we didn't find any host children, fallback to closest host parent. + var node = fiber; + while (true) { + switch (node.tag) { + case HostComponent: + hostInstances.add(node.stateNode); + return; + case HostPortal: + hostInstances.add(node.stateNode.containerInfo); + return; + case HostRoot: + hostInstances.add(node.stateNode.containerInfo); + return; + } + if (node.return === null) { + throw new Error("Expected to reach root first."); + } + node = node.return; + } + } +} - var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); - - if ( - fiber.type.contextTypes != null || - fiber.type.childContextTypes != null || - (instance !== null && typeof instance.getChildContext === "function") - ) { - if (warningsForRoot === undefined) { - warningsForRoot = []; - pendingLegacyContextWarning.set(strictRoot, warningsForRoot); +function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var node = fiber; + var foundHostInstances = false; + while (true) { + if (node.tag === HostComponent) { + // We got a match. + foundHostInstances = true; + hostInstances.add(node.stateNode); + // There may still be more, so keep searching. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - warningsForRoot.push(fiber); + if (node === fiber) { + return foundHostInstances; + } + while (node.sibling === null) { + if (node.return === null || node.return === fiber) { + return foundHostInstances; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; } - }; - - ReactStrictModeWarnings.flushLegacyContextWarning = function() { - pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { - var uniqueNames = new Set(); - fiberArray.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutLegacyContext.add(fiber.type); - }); - - var sortedNames = setToSortedString(uniqueNames); - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - - warningWithoutStack$1( - false, - "Legacy context API has been detected within a strict-mode tree: %s" + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-strict-mode-warnings", - strictRootComponentStack, - sortedNames - ); - }); - }; + } + return false; } function resolveDefaultProps(Component, baseProps) { @@ -5968,7 +7174,7 @@ var lastContextWithAllBitsObserved = null; var isDisallowedContextReadInDEV = false; -function resetContextDependences() { +function resetContextDependencies() { // This is called right before React yields execution, to ensure `readContext` // cannot be called outside the render phase. currentlyRenderingFiber = null; @@ -6113,11 +7319,11 @@ function propagateContextChange( var nextFiber = void 0; // Visit this fiber. - var list = fiber.contextDependencies; + var list = fiber.dependencies; if (list !== null) { nextFiber = fiber.child; - var dependency = list.first; + var dependency = list.firstContext; while (dependency !== null) { // Check if the context matches. if ( @@ -6128,7 +7334,7 @@ function propagateContextChange( if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate(renderExpirationTime); + var update = createUpdate(renderExpirationTime, null); 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 @@ -6224,17 +7430,18 @@ function prepareToReadContext(workInProgress, renderExpirationTime) { lastContextDependency = null; lastContextWithAllBitsObserved = null; - var currentDependencies = workInProgress.contextDependencies; - if ( - currentDependencies !== null && - currentDependencies.expirationTime >= renderExpirationTime - ) { - // Context list has a pending update. Mark that this fiber performed work. - markWorkInProgressReceivedUpdate(); + var dependencies = workInProgress.dependencies; + if (dependencies !== null) { + var firstContext = dependencies.firstContext; + if (firstContext !== null) { + if (dependencies.expirationTime >= renderExpirationTime) { + // Context list has a pending update. Mark that this fiber performed work. + markWorkInProgressReceivedUpdate(); + } + // Reset the work-in-progress list + dependencies.firstContext = null; + } } - - // Reset the work-in-progress list - workInProgress.contextDependencies = null; } function readContext(context, observedBits) { @@ -6279,16 +7486,20 @@ function readContext(context, observedBits) { (function() { if (!(currentlyRenderingFiber !== null)) { throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); } })(); // This is the first dependency for this component. Create a new list. lastContextDependency = contextItem; - currentlyRenderingFiber.contextDependencies = { - first: contextItem, - expirationTime: NoWork + currentlyRenderingFiber.dependencies = { + expirationTime: NoWork, + firstContext: contextItem, + listeners: null, + responders: null }; } else { // Append a new context item. @@ -6428,9 +7639,10 @@ function cloneUpdateQueue(currentQueue) { return queue; } -function createUpdate(expirationTime) { - return { +function createUpdate(expirationTime, suspenseConfig) { + var update = { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: UpdateState, payload: null, @@ -6439,6 +7651,10 @@ function createUpdate(expirationTime) { next: null, nextEffect: null }; + { + update.priority = getCurrentPriorityLevel(); + } + return update; } function appendUpdateToQueue(queue, update) { @@ -6691,7 +7907,7 @@ function processUpdateQueue( // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTime(updateExpirationTime); + markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. resultState = getStateFromUpdate( @@ -6805,8 +8021,10 @@ function callCallback(callback, context) { (function() { if (!(typeof callback === "function")) { throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ) ); } })(); @@ -6860,6 +8078,12 @@ function commitUpdateEffects(effect, instance) { } } +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; + +function requestCurrentSuspenseConfig() { + return ReactCurrentBatchConfig.suspense; +} + var fakeInternalInstance = {}; var isArray$1 = Array.isArray; @@ -6933,7 +8157,9 @@ var didWarnAboutInvalidateContextType = void 0; (function() { { throw ReactError( - "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + Error( + "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + ) ); } })(); @@ -6986,9 +8212,14 @@ var classComponentUpdater = { enqueueSetState: function(inst, payload, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.payload = payload; if (callback !== undefined && callback !== null) { { @@ -6997,16 +8228,23 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.tag = ReplaceState; update.payload = payload; @@ -7017,16 +8255,23 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.tag = ForceUpdate; if (callback !== undefined && callback !== null) { @@ -7036,7 +8281,9 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); } @@ -7619,11 +8866,6 @@ function mountClassInstance( } if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( - workInProgress, - instance - ); - ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -7631,7 +8873,7 @@ function mountClassInstance( } if (warnAboutDeprecatedLifecycles) { - ReactStrictModeWarnings.recordDeprecationWarnings( + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance ); @@ -8039,7 +9281,9 @@ var warnForMissingKey = function(child) {}; (function() { if (!(typeof child._store === "object")) { throw ReactError( - "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." + Error( + "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8101,7 +9345,9 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!(ownerFiber.tag === ClassComponent)) { throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); } })(); @@ -8110,9 +9356,11 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!inst) { throw ReactError( - "Missing owner for string ref " + - mixedRef + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + mixedRef + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8144,16 +9392,20 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!(typeof mixedRef === "string")) { throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); } })(); (function() { if (!element._owner) { throw ReactError( - "Element ref was specified as a string (" + - mixedRef + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + mixedRef + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } })(); @@ -8174,12 +9426,14 @@ function throwOnInvalidObjectType(returnFiber, newChild) { (function() { { throw ReactError( - "Objects are not valid as a React child (found: " + - (Object.prototype.toString.call(newChild) === "[object Object]" - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + - addendum + Error( + "Objects are not valid as a React child (found: " + + (Object.prototype.toString.call(newChild) === "[object Object]" + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + + addendum + ) ); } })(); @@ -8849,7 +10103,9 @@ function ChildReconciler(shouldTrackSideEffects) { (function() { if (!(typeof iteratorFn === "function")) { throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8904,7 +10160,7 @@ function ChildReconciler(shouldTrackSideEffects) { var newChildren = iteratorFn.call(newChildrenIterable); (function() { if (!(newChildren != null)) { - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); } })(); @@ -9282,8 +10538,10 @@ function ChildReconciler(shouldTrackSideEffects) { (function() { { throw ReactError( - (Component.displayName || Component.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (Component.displayName || Component.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) ); } })(); @@ -9304,7 +10562,7 @@ var mountChildFibers = ChildReconciler(false); function cloneChildFibers(current$$1, workInProgress) { (function() { if (!(current$$1 === null || workInProgress.child === current$$1.child)) { - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); } })(); @@ -9333,6 +10591,15 @@ function cloneChildFibers(current$$1, workInProgress) { newChild.sibling = null; } +// Reset a workInProgress child set to prepare it for a second pass. +function resetChildFibers(workInProgress, renderExpirationTime) { + var child = workInProgress.child; + while (child !== null) { + resetWorkInProgress(child, renderExpirationTime); + child = child.sibling; + } +} + var NO_CONTEXT = {}; var contextStackCursor$1 = createCursor(NO_CONTEXT); @@ -9343,7 +10610,9 @@ function requiredContext(c) { (function() { if (!(c !== NO_CONTEXT)) { throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -9402,46 +10671,188 @@ function pushHostContext(fiber) { push(contextStackCursor$1, nextContext, fiber); } -function pushHostContextForEventComponent(fiber) { - var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContextForEventComponent(context); - - // Don't push this Fiber's context unless it's unique. - if (context === nextContext) { +function popHostContext(fiber) { + // Do not pop unless this Fiber provided the current context. + // pushHostContext() only pushes Fibers that provide unique contexts. + if (contextFiberStackCursor.current !== fiber) { return; } - // Track the context and the Fiber that provided it. - // This enables us to pop only Fibers that provide unique contexts. - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, nextContext, fiber); + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); } -function pushHostContextForEventTarget(fiber) { - var context = requiredContext(contextStackCursor$1.current); - var eventTargetType = fiber.type.type; - var nextContext = getChildHostContextForEventTarget(context, eventTargetType); +var DefaultSuspenseContext = 0; - // Don't push this Fiber's context unless it's unique. - if (context === nextContext) { - return; +// The Suspense Context is split into two parts. The lower bits is +// inherited deeply down the subtree. The upper bits only affect +// this immediate suspense boundary and gets reset each new +// boundary or suspense list. +var SubtreeSuspenseContextMask = 1; + +// Subtree Flags: + +// InvisibleParentSuspenseContext indicates that one of our parent Suspense +// boundaries is not currently showing visible main content. +// Either because it is already showing a fallback or is not mounted at all. +// We can use this to determine if it is desirable to trigger a fallback at +// the parent. If not, then we might need to trigger undesirable boundaries +// and/or suspend the commit to avoid hiding the parent content. +var InvisibleParentSuspenseContext = 1; + +// Shallow Flags: + +// ForceSuspenseFallback can be used by SuspenseList to force newly added +// items into their fallback state during one of the render passes. +var ForceSuspenseFallback = 2; + +var suspenseStackCursor = createCursor(DefaultSuspenseContext); + +function hasSuspenseContext(parentContext, flag) { + return (parentContext & flag) !== 0; +} + +function setDefaultShallowSuspenseContext(parentContext) { + return parentContext & SubtreeSuspenseContextMask; +} + +function setShallowSuspenseContext(parentContext, shallowContext) { + return (parentContext & SubtreeSuspenseContextMask) | shallowContext; +} + +function addSubtreeSuspenseContext(parentContext, subtreeContext) { + return parentContext | subtreeContext; +} + +function pushSuspenseContext(fiber, newContext) { + push(suspenseStackCursor, newContext, fiber); +} + +function popSuspenseContext(fiber) { + pop(suspenseStackCursor, fiber); +} + +// TODO: This is now an empty object. Should we switch this to a boolean? +// Alternatively we can make this use an effect tag similar to SuspenseList. + +function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { + // If it was the primary children that just suspended, capture and render the + var nextState = workInProgress.memoizedState; + if (nextState !== null) { + return false; + } + var props = workInProgress.memoizedProps; + // In order to capture, the Suspense component must have a fallback prop. + if (props.fallback === undefined) { + return false; + } + // Regular boundaries always capture. + if (props.unstable_avoidThisFallback !== true) { + return true; } + // If it's a boundary we should avoid, then we prefer to bubble up to the + // parent boundary if it is currently invisible. + if (hasInvisibleParent) { + return false; + } + // If the parent is not able to handle it, we must handle it. + return true; +} - // Track the context and the Fiber that provided it. - // This enables us to pop only Fibers that provide unique contexts. - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, nextContext, fiber); +function findFirstSuspended(row) { + var node = row; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + return node; + } + } else if ( + node.tag === SuspenseListComponent && + // revealOrder undefined can't be trusted because it don't + // keep track of whether it suspended or not. + node.memoizedProps.revealOrder !== undefined + ) { + var didSuspend = (node.effectTag & DidCapture) !== NoEffect; + if (didSuspend) { + return node; + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) { + return null; + } + while (node.sibling === null) { + if (node.return === null || node.return === row) { + return null; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; } -function popHostContext(fiber) { - // Do not pop unless this Fiber provided the current context. - // pushHostContext() only pushes Fibers that provide unique contexts. - if (contextFiberStackCursor.current !== fiber) { - return; +var currentlyRenderingFiber$2 = null; +var currentListenerHookIndex = 0; + +function prepareToReadListenerHooks(workInProgress) { + currentlyRenderingFiber$2 = workInProgress; + currentListenerHookIndex = 0; +} + +function getListenerHooks() { + var listeners = void 0; + var dependencies = currentlyRenderingFiber$2.dependencies; + if (dependencies === null) { + dependencies = currentlyRenderingFiber$2.dependencies = { + expirationTime: NoWork, + firstContext: null, + listeners: [], + responders: null + }; + } + listeners = dependencies.listeners; + if (listeners === null) { + dependencies.listeners = listeners = []; + } + return listeners; +} + +function updateListenerHook(responder, props) { + var listeners = getListenerHooks(); + if (listeners.length === currentListenerHookIndex) { + listeners.push({ + responder: responder, + props: props + }); + currentListenerHookIndex++; + } else { + var currentListenerHook = listeners[currentListenerHookIndex++]; + currentListenerHook.responder = responder; + currentListenerHook.props = props; } +} - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); +function createResponderInstance( + responder, + responderProps, + responderState, + target, + fiber +) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState, + target: target + }; } var NoEffect$1 = /* */ 0; @@ -9601,7 +11012,9 @@ function throwInvalidHookError() { (function() { { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } })(); @@ -9782,7 +11195,9 @@ function renderWithHooks( (function() { if (!!didRenderTooFewHooks) { throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); } })(); @@ -9870,7 +11285,7 @@ function updateWorkInProgressHook() { (function() { if (!(nextCurrentHook !== null)) { throw ReactError( - "Rendered more hooks than during the previous render." + Error("Rendered more hooks than during the previous render.") ); } })(); @@ -9938,7 +11353,9 @@ function updateReducer(reducer, initialArg, init) { (function() { if (!(queue !== null)) { throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); } })(); @@ -9971,7 +11388,7 @@ function updateReducer(reducer, initialArg, init) { } hook.memoizedState = newState; - // Don't persist the state accumlated from the render phase updates to + // Don't persist the state accumulated from the render phase updates to // the base state unless the queue is empty. // TODO: Not sure if this is the desired semantics, but it's what we // do for gDSFP. I can't remember why. @@ -10037,7 +11454,10 @@ function updateReducer(reducer, initialArg, init) { // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTime(updateExpirationTime); + markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ); // Process this update. if (_update.eagerReducer === reducer) { @@ -10170,6 +11590,12 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { } function mountEffect(create, deps) { + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } return mountEffectImpl( Update | Passive, UnmountPassive | MountPassive, @@ -10179,6 +11605,12 @@ function mountEffect(create, deps) { } function updateEffect(create, deps) { + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } return updateEffectImpl( Update | Passive, UnmountPassive | MountPassive, @@ -10332,7 +11764,9 @@ function dispatchAction(fiber, queue, action) { (function() { if (!(numberOfReRenders < RE_RENDER_LIMIT)) { throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); } })(); @@ -10359,11 +11793,15 @@ function dispatchAction(fiber, queue, action) { didScheduleRenderPhaseUpdate = true; var update = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, next: null }; + { + update.priority = getCurrentPriorityLevel(); + } if (renderPhaseUpdates === null) { renderPhaseUpdates = new Map(); } @@ -10379,19 +11817,31 @@ function dispatchAction(fiber, queue, action) { lastRenderPhaseUpdate.next = update; } } else { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } var currentTime = requestCurrentTime(); - var _expirationTime = computeExpirationForFiber(currentTime, fiber); + var _suspenseConfig = requestCurrentSuspenseConfig(); + var _expirationTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); var _update2 = { expirationTime: _expirationTime, + suspenseConfig: _suspenseConfig, action: action, eagerReducer: null, eagerState: null, next: null }; + { + _update2.priority = getCurrentPriorityLevel(); + } + // Append the update to the end of the list. var _last = queue.last; if (_last === null) { @@ -10447,10 +11897,9 @@ function dispatchAction(fiber, queue, action) { } } { - // jest isn't a 'global', it's just exposed to tests via a wrapped function - // further, this isn't a test file, so flow doesn't recognize the symbol. So... - // $FlowExpectedError - because requirements don't give a damn about your type sigs. + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(fiber); warnIfNotCurrentlyActingUpdatesInDev(fiber); } } @@ -10470,7 +11919,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }; var HooksDispatcherOnMountInDEV = null; @@ -10576,6 +12026,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + mountHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10650,6 +12105,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + updateHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10724,6 +12184,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); return updateDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + updateHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10809,6 +12274,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); mountHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + warnInvalidHookAccess(); + mountHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10894,6 +12365,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); updateHookTypesDev(); return updateDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + warnInvalidHookAccess(); + updateHookTypesDev(); + updateListenerHook(responder, props); } }; } @@ -11163,7 +12640,9 @@ function prepareToHydrateHostInstance( (function() { { throw ReactError( - "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11193,7 +12672,9 @@ function prepareToHydrateHostTextInstance(fiber) { (function() { { throw ReactError( - "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11243,7 +12724,9 @@ function skipPastDehydratedSuspenseInstance(fiber) { (function() { { throw ReactError( - "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11252,7 +12735,9 @@ function skipPastDehydratedSuspenseInstance(fiber) { (function() { if (!suspenseInstance) { throw ReactError( - "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11340,6 +12825,9 @@ var didWarnAboutGetDerivedStateOnFunctionComponent = void 0; var didWarnAboutFunctionRefs = void 0; var didWarnAboutReassigningProps = void 0; var didWarnAboutMaxDuration = void 0; +var didWarnAboutRevealOrder = void 0; +var didWarnAboutTailOptions = void 0; +var didWarnAboutDefaultPropsOnFunctionComponent = void 0; { didWarnAboutBadClass = {}; @@ -11349,6 +12837,9 @@ var didWarnAboutMaxDuration = void 0; didWarnAboutFunctionRefs = {}; didWarnAboutReassigningProps = false; didWarnAboutMaxDuration = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; } function reconcileChildren( @@ -11450,6 +12941,9 @@ function updateForwardRef( // The rest is a fork of updateFunctionComponent var nextChildren = void 0; prepareToReadContext(workInProgress, renderExpirationTime); + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } { ReactCurrentOwner$3.current = workInProgress; setCurrentPhase("render"); @@ -11468,6 +12962,9 @@ function updateForwardRef( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } nextChildren = renderWithHooks( current$$1, workInProgress, @@ -11752,6 +13249,9 @@ function updateFunctionComponent( var nextChildren = void 0; prepareToReadContext(workInProgress, renderExpirationTime); + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } { ReactCurrentOwner$3.current = workInProgress; setCurrentPhase("render"); @@ -11770,6 +13270,9 @@ function updateFunctionComponent( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } nextChildren = renderWithHooks( current$$1, workInProgress, @@ -12023,7 +13526,9 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { (function() { if (!(updateQueue !== null)) { throw ReactError( - "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." + 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." + ) ); } })(); @@ -12121,10 +13626,13 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { // Check the host config to see if the children are offscreen/hidden. if ( - renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps) ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. workInProgress.expirationTime = workInProgress.childExpirationTime = Never; return null; @@ -12266,10 +13774,12 @@ function mountLazyComponent( (function() { { throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ) ); } })(); @@ -12358,7 +13868,9 @@ function mountIndeterminateComponent( var context = getMaskedContext(workInProgress, unmaskedContext); prepareToReadContext(workInProgress, renderExpirationTime); - + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } var value = void 0; { @@ -12472,6 +13984,9 @@ function mountIndeterminateComponent( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } value = renderWithHooks( null, workInProgress, @@ -12525,16 +14040,33 @@ function validateFunctionComponentInDev(workInProgress, Component) { } } - if (typeof Component.getDerivedStateFromProps === "function") { + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { var componentName = getComponentName(Component) || "Unknown"; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) { + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { warningWithoutStack$1( false, - "%s: Function components do not support getDerivedStateFromProps.", + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", componentName ); - didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true; + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } + + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + warningWithoutStack$1( + false, + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; } } @@ -12542,19 +14074,31 @@ function validateFunctionComponentInDev(workInProgress, Component) { typeof Component.contextType === "object" && Component.contextType !== null ) { - var _componentName2 = getComponentName(Component) || "Unknown"; + var _componentName3 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName2]) { + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { warningWithoutStack$1( false, "%s: Function components do not support contextType.", - _componentName2 + _componentName3 ); - didWarnAboutContextTypeOnFunctionComponent[_componentName2] = true; + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; } } } +// TODO: This is now an empty object. Should we just make it a boolean? +var SUSPENDED_MARKER = {}; + +function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { + // If the context is telling us that we should show a fallback, and we're not + // already showing content, then we should show the fallback instead. + return ( + hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && + (current$$1 === null || current$$1.memoizedState !== null) + ); +} + function updateSuspenseComponent( current$$1, workInProgress, @@ -12563,32 +14107,51 @@ function updateSuspenseComponent( var mode = workInProgress.mode; var nextProps = workInProgress.pendingProps; + // This is used by DevTools to force a boundary to suspend. { if (shouldSuspend(workInProgress)) { workInProgress.effectTag |= DidCapture; } } - // We should attempt to render the primary children unless this boundary - // already suspended during this render (`alreadyCaptured` is true). - var nextState = workInProgress.memoizedState; + var suspenseContext = suspenseStackCursor.current; - var nextDidTimeout = void 0; - if ((workInProgress.effectTag & DidCapture) === NoEffect) { - // This is the first attempt. - nextState = null; - nextDidTimeout = false; - } else { + var nextState = null; + var nextDidTimeout = false; + + if ( + (workInProgress.effectTag & DidCapture) !== NoEffect || + shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) + ) { // Something in this boundary's subtree already suspended. Switch to // rendering the fallback children. - nextState = { - fallbackExpirationTime: - nextState !== null ? nextState.fallbackExpirationTime : NoWork - }; + nextState = SUSPENDED_MARKER; nextDidTimeout = true; workInProgress.effectTag &= ~DidCapture; + } else { + // Attempting the main content + if (current$$1 === null || current$$1.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); + { if ("maxDuration" in nextProps) { if (!didWarnAboutMaxDuration) { @@ -12641,6 +14204,7 @@ function updateSuspenseComponent( tryToClaimNextHydratableInstance(workInProgress); // This could've changed the tag if this was a dehydrated suspense component. if (workInProgress.tag === DehydratedSuspenseComponent) { + popSuspenseContext(workInProgress); return updateDehydratedSuspenseComponent( null, workInProgress, @@ -12661,15 +14225,21 @@ function updateSuspenseComponent( NoWork, null ); + primaryChildFragment.return = workInProgress; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var progressedState = workInProgress.memoizedState; var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child; primaryChildFragment.child = progressedPrimaryChild; + var progressedChild = progressedPrimaryChild; + while (progressedChild !== null) { + progressedChild.return = primaryChildFragment; + progressedChild = progressedChild.sibling; + } } var fallbackChildFragment = createFiberFromFragment( @@ -12678,12 +14248,12 @@ function updateSuspenseComponent( renderExpirationTime, null ); + fallbackChildFragment.return = workInProgress; primaryChildFragment.sibling = fallbackChildFragment; child = primaryChildFragment; // Skip the primary children, and continue working on the // fallback children. next = fallbackChildFragment; - child.return = next.return = workInProgress; } else { // Mount the primary children without an intermediate fragment fiber. var nextPrimaryChildren = nextProps.children; @@ -12712,9 +14282,10 @@ function updateSuspenseComponent( currentPrimaryChildFragment.pendingProps, NoWork ); + _primaryChildFragment.return = workInProgress; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var _progressedState = workInProgress.memoizedState; var _progressedPrimaryChild = _progressedState !== null @@ -12722,6 +14293,11 @@ function updateSuspenseComponent( : workInProgress.child; if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { _primaryChildFragment.child = _progressedPrimaryChild; + var _progressedChild = _progressedPrimaryChild; + while (_progressedChild !== null) { + _progressedChild.return = _primaryChildFragment; + _progressedChild = _progressedChild.sibling; + } } } @@ -12740,17 +14316,18 @@ function updateSuspenseComponent( // Clone the fallback child fragment, too. These we'll continue // working on. - var _fallbackChildFragment = (_primaryChildFragment.sibling = createWorkInProgress( + var _fallbackChildFragment = createWorkInProgress( currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime - )); + ); + _fallbackChildFragment.return = workInProgress; + _primaryChildFragment.sibling = _fallbackChildFragment; child = _primaryChildFragment; _primaryChildFragment.childExpirationTime = NoWork; // Skip the primary children, and continue working on the // fallback children. next = _fallbackChildFragment; - child.return = next.return = workInProgress; } else { // No longer suspended. Switch back to showing the primary children, // and remove the intermediate fragment fiber. @@ -12788,21 +14365,30 @@ function updateSuspenseComponent( NoWork, null ); + _primaryChildFragment2.return = workInProgress; _primaryChildFragment2.child = _currentPrimaryChild; + if (_currentPrimaryChild !== null) { + _currentPrimaryChild.return = _primaryChildFragment2; + } // Even though we're creating a new fiber, there are no new children, // because we're reusing an already mounted tree. So we don't need to // schedule a placement. // primaryChildFragment.effectTag |= Placement; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var _progressedState2 = workInProgress.memoizedState; var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child; _primaryChildFragment2.child = _progressedPrimaryChild2; + var _progressedChild2 = _progressedPrimaryChild2; + while (_progressedChild2 !== null) { + _progressedChild2.return = _primaryChildFragment2; + _progressedChild2 = _progressedChild2.sibling; + } } // Because primaryChildFragment is a new fiber that we're inserting as the @@ -12819,19 +14405,20 @@ function updateSuspenseComponent( } // Create a fragment from the fallback children, too. - var _fallbackChildFragment2 = (_primaryChildFragment2.sibling = createFiberFromFragment( + var _fallbackChildFragment2 = createFiberFromFragment( _nextFallbackChildren2, mode, renderExpirationTime, null - )); + ); + _fallbackChildFragment2.return = workInProgress; + _primaryChildFragment2.sibling = _fallbackChildFragment2; _fallbackChildFragment2.effectTag |= Placement; child = _primaryChildFragment2; _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the // fallback children. next = _fallbackChildFragment2; - child.return = next.return = workInProgress; } else { // Still haven't timed out. Continue rendering the children, like we // normally do. @@ -12866,7 +14453,9 @@ function retrySuspenseComponentWithoutHydrating( (function() { if (!(returnFiber !== null)) { throw ReactError( - "Suspense boundaries are never on the root. This is probably a bug in React." + Error( + "Suspense boundaries are never on the root. This is probably a bug in React." + ) ); } })(); @@ -12880,6 +14469,8 @@ function retrySuspenseComponentWithoutHydrating( current$$1.nextEffect = null; current$$1.effectTag = Deletion; + popSuspenseContext(workInProgress); + // Upgrade this work in progress to a real Suspense component. workInProgress.tag = SuspenseComponent; workInProgress.stateNode = null; @@ -12895,6 +14486,10 @@ function updateDehydratedSuspenseComponent( workInProgress, renderExpirationTime ) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); var suspenseInstance = workInProgress.stateNode; if (current$$1 === null) { // During the first pass, we'll bail out and not drill into the children. @@ -12987,6 +14582,382 @@ function updateDehydratedSuspenseComponent( } } +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderExpirationTime +) { + // 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; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + if (node.expirationTime < renderExpirationTime) { + node.expirationTime = renderExpirationTime; + } + var alternate = node.alternate; + if ( + alternate !== null && + alternate.expirationTime < renderExpirationTime + ) { + alternate.expirationTime = renderExpirationTime; + } + scheduleWorkOnParentPath(node.return, renderExpirationTime); + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) { + return; + } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} + +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; + } + row = row.sibling; + } + return lastContentRow; +} + +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + case "forward": + case "backward": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + default: + warning$1( + false, + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { + warning$1( + false, + "%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; + warning$1( + false, + '"%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; + warning$1( + false, + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); + } + } + } +} + +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + warning$1( + false, + "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; + } + } + 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 { + var iteratorFn = getIteratorFn(children); + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + _i++; + } + } + } else { + warning$1( + false, + '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 +) { + var renderState = workInProgress.memoizedState; + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailExpiration = 0; + 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. +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + 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$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + + var suspenseContext = suspenseStackCursor.current; + + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.effectTag |= DidCapture; + } else { + var didSuspendBefore = + current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; + 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, + renderExpirationTime + ); + } + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } + pushSuspenseContext(workInProgress, suspenseContext); + + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched 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 = void 0; + 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; + } + case "together": { + initSuspenseListRenderState( + workInProgress, + 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 workInProgress.child; +} + function updatePortalComponent( current$$1, workInProgress, @@ -13150,11 +15121,15 @@ function updateContextConsumer( return workInProgress.child; } -function updateEventComponent$1( +function updateFundamentalComponent$1( current$$1, workInProgress, renderExpirationTime ) { + var fundamentalImpl = workInProgress.type.impl; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; @@ -13164,38 +15139,6 @@ function updateEventComponent$1( nextChildren, renderExpirationTime ); - pushHostContextForEventComponent(workInProgress); - return workInProgress.child; -} - -function updateEventTarget(current$$1, workInProgress, renderExpirationTime) { - var type = workInProgress.type.type; - var nextProps = workInProgress.pendingProps; - var eventTargetChild = getEventTargetChildElement(type, nextProps); - - { - !(nextProps.children == null) - ? warning$1(false, "Event targets should not have children.") - : void 0; - } - if (eventTargetChild !== null) { - var child = (workInProgress.child = createFiberFromTypeAndProps( - eventTargetChild.type, - null, - eventTargetChild.props, - null, - workInProgress.mode, - renderExpirationTime - )); - child.return = workInProgress; - - if (current$$1 === null || current$$1.child === null) { - child.effectTag = Placement; - } - } else { - reconcileChildren(current$$1, workInProgress, null, renderExpirationTime); - } - pushHostContextForEventTarget(workInProgress); return workInProgress.child; } @@ -13211,8 +15154,8 @@ function bailoutOnAlreadyFinishedWork( cancelWorkTimer(workInProgress); if (current$$1 !== null) { - // Reuse previous context list - workInProgress.contextDependencies = current$$1.contextDependencies; + // Reuse previous dependencies + workInProgress.dependencies = current$$1.dependencies; } if (enableProfilerTimer) { @@ -13335,6 +15278,18 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { break; case HostComponent: pushHostContext(workInProgress); + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(workInProgress.type, newProps) + ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + // Schedule this fiber to re-render at offscreen priority. Then bailout. + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } break; case ClassComponent: { var Component = workInProgress.type; @@ -13381,6 +15336,10 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ); } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient // priority. Bailout. var child = bailoutOnAlreadyFinishedWork( @@ -13396,11 +15355,20 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { return null; } } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } break; } case DehydratedSuspenseComponent: { if (enableSuspenseServerRenderer) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has // been unsuspended it has committed as a regular Suspense component. // If it needs to be retried, it should have work scheduled on it. @@ -13408,15 +15376,46 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } break; } - case EventComponent: - if (enableEventAPI) { - pushHostContextForEventComponent(workInProgress); + case SuspenseListComponent: { + var didSuspendBefore = + (current$$1.effectTag & DidCapture) !== NoEffect; + + var childExpirationTime = workInProgress.childExpirationTime; + if (childExpirationTime < renderExpirationTime) { + // 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. + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (didSuspendBefore) { + workInProgress.effectTag |= DidCapture; + } + return null; } - break; - case EventTarget: { - if (enableEventAPI) { - pushHostContextForEventTarget(workInProgress); + + if (didSuspendBefore) { + // 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$$1, + workInProgress, + renderExpirationTime + ); + } + + // 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; } + pushSuspenseContext(workInProgress, suspenseStackCursor.current); break; } } @@ -13601,19 +15600,16 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } break; } - case EventComponent: { - if (enableEventAPI) { - return updateEventComponent$1( - current$$1, - workInProgress, - renderExpirationTime - ); - } - break; + case SuspenseListComponent: { + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } - case EventTarget: { - if (enableEventAPI) { - return updateEventTarget( + case FundamentalComponent: { + if (enableFundamentalAPI) { + return updateFundamentalComponent$1( current$$1, workInProgress, renderExpirationTime @@ -13625,12 +15621,28 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { (function() { { throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); } +function createFundamentalStateInstance(currentFiber, props, impl, state) { + return { + currentFiber: currentFiber, + impl: impl, + instance: null, + prevProps: null, + props: props, + state: state + }; +} + +var emptyObject$1 = {}; +var isArray$2 = Array.isArray; + function markUpdate(workInProgress) { // Tag the fiber with an update effect. This turns a Placement into // a PlacementAndUpdate. @@ -13660,6 +15672,8 @@ if (supportsMutation) { while (node !== null) { if (node.tag === HostComponent || node.tag === HostText) { appendInitialChild(parent, node.stateNode); + } else if (node.tag === FundamentalComponent) { + appendInitialChild(parent, node.stateNode.instance); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -13764,6 +15778,15 @@ if (supportsMutation) { _instance = cloneHiddenTextInstance(_instance, text, node); } appendInitialChild(parent, _instance); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance2 = node.stateNode.instance; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props = node.memoizedProps; + var _type = node.type; + _instance2 = cloneHiddenInstance(_instance2, _type, _props, node); + } + appendInitialChild(parent, _instance2); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -13842,13 +15865,22 @@ if (supportsMutation) { } appendChildToContainerChildSet(containerChildSet, instance); } else if (node.tag === HostText) { - var _instance2 = node.stateNode; + var _instance3 = node.stateNode; if (needsVisibilityToggle && isHidden) { // This child is inside a timed out tree. Hide it. var text = node.memoizedProps; - _instance2 = cloneHiddenTextInstance(_instance2, text, node); + _instance3 = cloneHiddenTextInstance(_instance3, text, node); + } + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance4 = node.stateNode.instance; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props2 = node.memoizedProps; + var _type2 = node.type; + _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node); } - appendChildToContainerChildSet(containerChildSet, _instance2); + appendChildToContainerChildSet(containerChildSet, _instance4); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -14024,6 +16056,69 @@ if (supportsMutation) { }; } +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + tailNode = tailNode.sibling; + } + // Next we're simply going to delete all insertions after the + // last rendered item. + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } + break; + } + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } + _tailNode = _tailNode.sibling; + } + // Next we're simply going to delete all insertions after the + // last rendered item. + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + break; + } + } +} + function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; @@ -14074,6 +16169,20 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); + if (enableFlareAPI) { + var prevResponders = current.memoizedProps.responders; + var nextResponders = newProps.responders; + var instance = workInProgress.stateNode; + if (prevResponders !== nextResponders) { + updateEventResponders( + nextResponders, + instance, + rootContainerInstance, + workInProgress + ); + } + } + if (current.ref !== workInProgress.ref) { markRef$1(workInProgress); } @@ -14082,7 +16191,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { if (!(workInProgress.stateNode !== null)) { throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14111,7 +16222,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } else { - var instance = createInstance( + var _instance5 = createInstance( type, newProps, rootContainerInstance, @@ -14119,14 +16230,26 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress ); - appendAllChildren(instance, workInProgress, false, false); + appendAllChildren(_instance5, workInProgress, false, false); + + if (enableFlareAPI) { + var responders = newProps.responders; + if (responders != null) { + updateEventResponders( + responders, + _instance5, + rootContainerInstance, + workInProgress + ); + } + } // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. if ( finalizeInitialChildren( - instance, + _instance5, type, newProps, rootContainerInstance, @@ -14135,7 +16258,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { ) { markUpdate(workInProgress); } - workInProgress.stateNode = instance; + workInProgress.stateNode = _instance5; } if (workInProgress.ref !== null) { @@ -14157,7 +16280,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { if (!(workInProgress.stateNode !== null)) { throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14184,6 +16309,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { case ForwardRef: break; case SuspenseComponent: { + popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; if ((workInProgress.effectTag & DidCapture) !== NoEffect) { // Something suspended. Re-render with the fallback children. @@ -14204,15 +16330,8 @@ function completeWork(current, workInProgress, renderExpirationTime) { prevDidTimeout = prevState !== null; if (!nextDidTimeout && prevState !== null) { // We just switched from the fallback to the normal children. - - // Mark the event time of the switching from fallback to normal children, - // based on the start of when we first showed the fallback. This time - var fallbackExpirationTime = prevState.fallbackExpirationTime; - markRenderEventTime(fallbackExpirationTime); - // Delete the fallback. // TODO: Would it be better to store the fallback fragment on - // the stateNode during the begin phase? var currentFallbackChild = current.child.sibling; if (currentFallbackChild !== null) { // Deletions go at the beginning of the return fiber's effect list @@ -14230,13 +16349,37 @@ function completeWork(current, workInProgress, renderExpirationTime) { } if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in concurrent mode we can suspend, + // If this subtreee is running in batched 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 & ConcurrentMode) !== NoContext) { - renderDidSuspend(); + if ((workInProgress.mode & BatchedMode) !== 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(); + } } } @@ -14260,6 +16403,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.effectTag |= Update; } } + if ( + enableSuspenseCallback && + workInProgress.updateQueue !== null && + workInProgress.memoizedProps.suspenseCallback != null + ) { + // Always notify the callback + workInProgress.effectTag |= Update; + } break; } case Fragment: @@ -14291,15 +16442,21 @@ function completeWork(current, workInProgress, renderExpirationTime) { } case DehydratedSuspenseComponent: { if (enableSuspenseServerRenderer) { + popSuspenseContext(workInProgress); if (current === null) { var _wasHydrated2 = popHydrationState(workInProgress); (function() { if (!_wasHydrated2) { throw ReactError( - "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ) ); } })(); + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } skipPastDehydratedSuspenseInstance(workInProgress); } else if ((workInProgress.effectTag & DidCapture) === NoEffect) { // This boundary did not suspend so it's now hydrated. @@ -14314,55 +16471,239 @@ function completeWork(current, workInProgress, renderExpirationTime) { } break; } - case EventComponent: { - if (enableEventAPI) { - popHostContext(workInProgress); - var _rootContainerInstance2 = getRootHostContainer(); - var responder = workInProgress.type.responder; - var eventComponentInstance = workInProgress.stateNode; - - if (eventComponentInstance === null) { - var responderState = null; - if (responder.createInitialState !== undefined) { - responderState = responder.createInitialState(newProps); + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. We don't do anything + // in this mode. + break; + } + + var didSuspendAlready = + (workInProgress.effectTag & DidCapture) !== NoEffect; + + var renderedTail = renderState.rendering; + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.effectTag & DidCapture) === NoEffect); + if (!cannotBeSuspended) { + var row = workInProgress.child; + while (row !== null) { + var suspended = findFirstSuspended(row); + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.effectTag |= 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. + var newThennables = suspended.updateQueue; + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.effectTag |= 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. + workInProgress.firstEffect = workInProgress.lastEffect = null; + // Reset the child fibers to their original state. + resetChildFibers(workInProgress, renderExpirationTime); + + // Set up the Suspense Context to force suspense and immediately + // rerender the children. + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } + row = row.sibling; + } } - eventComponentInstance = workInProgress.stateNode = { - currentFiber: workInProgress, - props: newProps, - responder: responder, - rootEventTypes: null, - rootInstance: _rootContainerInstance2, - state: responderState - }; - markUpdate(workInProgress); } else { - // Update the props on the event component state node - eventComponentInstance.props = newProps; - // Update the root container, so we can properly unmount events at some point - eventComponentInstance.rootInstance = _rootContainerInstance2; - // Update the current fiber - eventComponentInstance.currentFiber = workInProgress; - updateEventComponent(eventComponentInstance); + cutOffTailIfNeeded(renderState, false); + } + // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + if (_suspended !== null) { + workInProgress.effectTag |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, true); + // This might have been modified. + if ( + renderState.tail === null && + renderState.tailMode === "hidden" + ) { + // We need to delete the row we just rendered. + // Ensure we transfer the update queue to the parent. + var _newThennables = _suspended.updateQueue; + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.effectTag |= Update; + } + // Reset the effect list to what it w as 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. + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } + // We're done. + return null; + } + } else if ( + now() > renderState.tailExpiration && + renderExpirationTime > Never + ) { + // 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.effectTag |= 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. If we can show + // them, then they really have the same priority as this render. + // So we'll pick it back up the very next render pass once we've had + // an opportunity to yield for paint. + + var nextPriority = renderExpirationTime - 1; + workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; + if (enableSchedulerTracing) { + markSpawnedWork(nextPriority); + } + } + } + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } + renderState.last = renderedTail; + } + } + + if (renderState.tail !== null) { + // We still have tail rows to render. + if (renderState.tailExpiration === 0) { + // Heuristic for how long we're willing to spend rendering rows + // until we just give up and show what we have so far. + var TAIL_EXPIRATION_TIMEOUT_MS = 500; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + } + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.lastEffect = workInProgress.lastEffect; + next.sibling = null; + + // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + var suspenseContext = suspenseStackCursor.current; + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } + pushSuspenseContext(workInProgress, suspenseContext); + // Do a pass over the next row. + return next; } break; } - case EventTarget: { - if (enableEventAPI) { - popHostContext(workInProgress); - var _type = workInProgress.type.type; - var _rootContainerInstance3 = getRootHostContainer(); - var shouldUpdate = handleEventTarget( - _type, - newProps, - _rootContainerInstance3, - workInProgress - ); - // Update the latest props on the stateNode. This is used - // during the event phase to find the most current props. - workInProgress.stateNode.props = newProps; - if (shouldUpdate) { - markUpdate(workInProgress); + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalImpl = workInProgress.type.impl; + var fundamentalInstance = workInProgress.stateNode; + + if (fundamentalInstance === null) { + var getInitialState = fundamentalImpl.getInitialState; + var fundamentalState = void 0; + if (getInitialState !== undefined) { + fundamentalState = getInitialState(newProps); + } + fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance( + workInProgress, + newProps, + fundamentalImpl, + fundamentalState || {} + ); + var _instance6 = getFundamentalComponentInstance(fundamentalInstance); + fundamentalInstance.instance = _instance6; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } + appendAllChildren(_instance6, workInProgress, false, false); + mountFundamentalComponent(fundamentalInstance); + } else { + // We fire update in commit phase + var prevProps = fundamentalInstance.props; + fundamentalInstance.prevProps = prevProps; + fundamentalInstance.props = newProps; + fundamentalInstance.currentFiber = workInProgress; + if (supportsPersistence) { + var _instance7 = cloneFundamentalInstance(fundamentalInstance); + fundamentalInstance.instance = _instance7; + appendAllChildren(_instance7, workInProgress, false, false); + } + var shouldUpdate = shouldUpdateFundamentalComponent( + fundamentalInstance + ); + if (shouldUpdate) { + markUpdate(workInProgress); + } } } break; @@ -14371,7 +16712,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { { throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14380,15 +16723,263 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } -function shouldCaptureSuspense(workInProgress) { - // In order to capture, the Suspense component must have a fallback prop. - if (workInProgress.memoizedProps.fallback === undefined) { - return false; +function mountEventResponder$1( + responder, + responderProps, + instance, + rootContainerInstance, + fiber, + respondersMap +) { + var responderState = emptyObject$1; + var getInitialState = responder.getInitialState; + if (getInitialState !== null) { + responderState = getInitialState(responderProps); + } + var responderInstance = createResponderInstance( + responder, + responderProps, + responderState, + instance, + fiber + ); + mountResponderInstance( + responder, + responderInstance, + responderProps, + responderState, + instance, + rootContainerInstance + ); + respondersMap.set(responder, responderInstance); +} + +function updateEventResponder( + responder, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance +) { + (function() { + if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) { + throw ReactError( + Error( + "An invalid value was used as an event responder. Expect one or many event responders created via React.unstable_createResponer()." + ) + ); + } + })(); + if (visistedResponders.has(responder)) { + // show warning + return; + } + visistedResponders.add(responder); + var responderInstance = respondersMap.get(responder); + + if (responderInstance === undefined) { + // Mount + mountEventResponder$1( + responder, + props, + instance, + rootContainerInstance, + fiber, + respondersMap + ); + } else { + // Update + responderInstance.props = props; + responderInstance.fiber = fiber; + } +} + +function updateEventResponders( + responders, + instance, + rootContainerInstance, + fiber +) { + var visistedResponders = new Set(); + var dependencies = fiber.dependencies; + if (responders != null) { + if (dependencies === null) { + dependencies = fiber.dependencies = { + expirationTime: NoWork, + firstContext: null, + listeners: null, + responders: new Map() + }; + } + var respondersMap = dependencies.responders; + if (respondersMap === null) { + respondersMap = new Map(); + } + if (isArray$2(responders)) { + for (var i = 0, length = responders.length; i < length; i++) { + var _responders$i = responders[i], + type = _responders$i.type, + props = _responders$i.props; + + updateEventResponder( + type, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance + ); + } + } else { + var type = responders.type, + props = responders.props; + + updateEventResponder( + type, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance + ); + } + } + if (dependencies !== null) { + var _respondersMap = dependencies.responders; + if (_respondersMap !== null) { + // Unmount + var mountedResponders = Array.from(_respondersMap.keys()); + for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { + var mountedResponder = mountedResponders[_i]; + if (!visistedResponders.has(mountedResponder)) { + var responderInstance = _respondersMap.get(mountedResponder); + unmountResponderInstance(responderInstance); + _respondersMap.delete(mountedResponder); + } + } + } + } +} + +function unwindWork(workInProgress, renderExpirationTime) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; + if (isContextProvider(Component)) { + popContext(workInProgress); + } + var effectTag = workInProgress.effectTag; + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + return null; + } + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; + (function() { + if (!((_effectTag & DidCapture) === NoEffect)) { + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + } + })(); + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var _effectTag2 = workInProgress.effectTag; + if (_effectTag2 & ShouldCapture) { + workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; + // Captured a suspense effect. Re-render the boundary. + return workInProgress; + } + return null; + } + case DehydratedSuspenseComponent: { + if (enableSuspenseServerRenderer) { + // TODO: popHydrationState + popSuspenseContext(workInProgress); + var _effectTag3 = workInProgress.effectTag; + if (_effectTag3 & ShouldCapture) { + workInProgress.effectTag = + (_effectTag3 & ~ShouldCapture) | DidCapture; + // Captured a suspense effect. Re-render the boundary. + return workInProgress; + } + } + 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. + return null; + } + case HostPortal: + popHostContainer(workInProgress); + return null; + case ContextProvider: + popProvider(workInProgress); + return null; + default: + return null; + } +} + +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } + break; + } + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + break; + } + case HostComponent: { + popHostContext(interruptedWork); + break; + } + case HostPortal: + popHostContainer(interruptedWork); + break; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; + case DehydratedSuspenseComponent: + if (enableSuspenseServerRenderer) { + // TODO: popHydrationState + popSuspenseContext(interruptedWork); + } + break; + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; + case ContextProvider: + popProvider(interruptedWork); + break; + default: + break; } - // If it was the primary children that just suspended, capture and render the - // fallback. Otherwise, don't capture and bubble to the next boundary. - var nextState = workInProgress.memoizedState; - return nextState === null; } function createCapturedValue(value, source) { @@ -14399,50 +16990,26 @@ function createCapturedValue(value, source) { source: source, stack: getStackByFiberInDevAndProd(source) }; -} - -// Module provided by RN: -/** - * Intercept lifecycle errors and ensure they are shown with the correct stack - * trace within the native redbox component. - */ -function showErrorDialog(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - - var errorToHandle = void 0; - - // Typically Errors are thrown but eg strings or null can be thrown as well. - if (error instanceof Error) { - var message = error.message, - name = error.name; - - var summary = message ? name + ": " + message : name; - - errorToHandle = error; +} - try { - errorToHandle.message = - summary + "\n\nThis error is located at:" + componentStack; - } catch (e) {} - } else if (typeof error === "string") { - errorToHandle = new Error( - error + "\n\nThis error is located at:" + componentStack +// Module provided by RN: +(function() { + if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog + .showErrorDialog === "function" + ) + ) { + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") ); - } else { - errorToHandle = new Error("Unspecified error at:" + componentStack); } +})(); - ReactNativePrivateInterface.ExceptionsManager.handleException( - errorToHandle, - false +function showErrorDialog(capturedError) { + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError ); - - // Return false here to prevent ReactFiberErrorLogger default behavior of - // logging error details to console.error. Calls to console.error are - // automatically routed to the native redbox controller, which we've already - // done above by calling ExceptionsManager. - return false; } function logCapturedError(capturedError) { @@ -14692,14 +17259,15 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case HostText: case HostPortal: case IncompleteClassComponent: - case EventTarget: // Nothing to do for these component types return; default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -14768,8 +17336,19 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } function commitPassiveHookEffects(finishedWork) { - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if ((finishedWork.effectTag & Passive) !== NoEffect) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + break; + } + default: + break; + } + } } function commitLifeCycles( @@ -14967,73 +17546,43 @@ function commitLifeCycles( if (enableProfilerTimer) { var onRender = finishedWork.memoizedProps.onRender; - if (enableSchedulerTracing) { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime(), - finishedRoot.memoizedInteractions - ); - } else { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime() - ); + if (typeof onRender === "function") { + if (enableSchedulerTracing) { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime(), + finishedRoot.memoizedInteractions + ); + } else { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime() + ); + } } } return; } case SuspenseComponent: + case SuspenseListComponent: case IncompleteClassComponent: + case FundamentalComponent: return; - case EventTarget: { - if (enableEventAPI) { - var _type = finishedWork.type.type; - var _props = finishedWork.memoizedProps; - var _instance3 = finishedWork.stateNode; - var parentInstance = null; - - var node = finishedWork.return; - // Traverse up the fiber tree until we find the parent host node. - while (node !== null) { - if (node.tag === HostComponent) { - parentInstance = node.stateNode; - break; - } else if (node.tag === HostRoot) { - parentInstance = node.stateNode.containerInfo; - break; - } - node = node.return; - } - (function() { - if (!(parentInstance !== null)) { - throw ReactError( - "This should have a parent host component initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); - commitEventTarget(_type, _props, _instance3, parentInstance); - } - return; - } - case EventComponent: { - if (enableEventAPI) { - mountEventComponent(finishedWork.stateNode); - } - return; - } default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15054,11 +17603,11 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { unhideInstance(node.stateNode, node.memoizedProps); } } else if (node.tag === HostText) { - var _instance4 = node.stateNode; + var _instance3 = node.stateNode; if (isHidden) { - hideTextInstance(_instance4); + hideTextInstance(_instance3); } else { - unhideTextInstance(_instance4, node.memoizedProps); + unhideTextInstance(_instance3, node.memoizedProps); } } else if ( node.tag === SuspenseComponent && @@ -15169,6 +17718,25 @@ function commitUnmount(current$$1) { return; } case HostComponent: { + if (enableFlareAPI) { + var dependencies = current$$1.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + for ( + var i = 0, length = responderInstances.length; + i < length; + i++ + ) { + var responderInstance = responderInstances[i]; + unmountResponderInstance(responderInstance); + } + dependencies.responders = null; + } + } + } safelyDetachRef(current$$1); return; } @@ -15183,11 +17751,13 @@ function commitUnmount(current$$1) { } return; } - case EventComponent: { - if (enableEventAPI) { - var eventComponentInstance = current$$1.stateNode; - unmountEventComponent(eventComponentInstance); - current$$1.stateNode = null; + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = current$$1.stateNode; + if (fundamentalInstance !== null) { + unmountFundamentalComponent(fundamentalInstance); + current$$1.stateNode = null; + } } } } @@ -15237,12 +17807,14 @@ function detachFiber(current$$1) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; if (alternate !== null) { alternate.return = null; alternate.child = null; alternate.memoizedState = null; alternate.updateQueue = null; + alternate.dependencies = null; } } @@ -15266,8 +17838,7 @@ function commitContainer(finishedWork) { case ClassComponent: case HostComponent: case HostText: - case EventTarget: - case EventComponent: { + case FundamentalComponent: { return; } case HostRoot: @@ -15282,7 +17853,9 @@ function commitContainer(finishedWork) { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15301,7 +17874,9 @@ function getHostParentFiber(fiber) { (function() { { throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15371,25 +17946,33 @@ function commitPlacement(finishedWork) { // Note: these two variables *must* always be updated together. var parent = void 0; var isContainer = void 0; - + var parentStateNode = parentFiber.stateNode; switch (parentFiber.tag) { case HostComponent: - parent = parentFiber.stateNode; + parent = parentStateNode; isContainer = false; break; case HostRoot: - parent = parentFiber.stateNode.containerInfo; + parent = parentStateNode.containerInfo; isContainer = true; break; case HostPortal: - parent = parentFiber.stateNode.containerInfo; + parent = parentStateNode.containerInfo; isContainer = true; break; + case FundamentalComponent: + if (enableFundamentalAPI) { + parent = parentStateNode.instance; + isContainer = false; + } + // eslint-disable-next-line-no-fallthrough default: (function() { { throw ReactError( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15406,8 +17989,9 @@ function commitPlacement(finishedWork) { // children to find all the terminal nodes. var node = finishedWork; while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - var stateNode = node.stateNode; + var isHost = node.tag === HostComponent || node.tag === HostText; + if (isHost || node.tag === FundamentalComponent) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; if (before) { if (isContainer) { insertInContainerBefore(parent, stateNode, before); @@ -15463,23 +18047,31 @@ function unmountHostComponents(current$$1) { (function() { if (!(parent !== null)) { throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); + var parentStateNode = parent.stateNode; switch (parent.tag) { case HostComponent: - currentParent = parent.stateNode; + currentParent = parentStateNode; currentParentIsContainer = false; break findParent; case HostRoot: - currentParent = parent.stateNode.containerInfo; + currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; case HostPortal: - currentParent = parent.stateNode.containerInfo; + currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; + case FundamentalComponent: + if (enableFundamentalAPI) { + currentParent = parentStateNode.instance; + currentParentIsContainer = false; + } } parent = parent.return; } @@ -15496,6 +18088,16 @@ function unmountHostComponents(current$$1) { removeChild(currentParent, node.stateNode); } // Don't visit children because we already visited them. + } else if (node.tag === FundamentalComponent) { + var fundamentalNode = node.stateNode.instance; + commitNestedUnmounts(node); + // After all the children have unmounted, it is now safe to remove the + // node from the tree. + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, fundamentalNode); + } else { + removeChild(currentParent, fundamentalNode); + } } else if ( enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent @@ -15574,6 +18176,11 @@ function commitWork(current$$1, finishedWork) { } case SuspenseComponent: { commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } } @@ -15626,7 +18233,9 @@ function commitWork(current$$1, finishedWork) { (function() { if (!(finishedWork.stateNode !== null)) { throw ReactError( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15639,9 +18248,6 @@ function commitWork(current$$1, finishedWork) { commitTextUpdate(textInstance, oldText, newText); return; } - case EventTarget: { - return; - } case HostRoot: { return; } @@ -15650,19 +18256,30 @@ function commitWork(current$$1, finishedWork) { } case SuspenseComponent: { commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } case IncompleteClassComponent: { return; } - case EventComponent: { + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = finishedWork.stateNode; + updateFundamentalComponent(fundamentalInstance); + } return; } default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15680,25 +18297,31 @@ function commitSuspenseComponent(finishedWork) { } else { newDidTimeout = true; primaryChildParent = finishedWork.child; - if (newState.fallbackExpirationTime === NoWork) { - // If the children had not already timed out, record the time. - // This is used to compute the elapsed time during subsequent - // attempts to render the children. - // We model this as a normal pri expiration time since that's - // how we infer start time for updates. - newState.fallbackExpirationTime = computeAsyncExpirationNoBucket( - requestCurrentTime() - ); - } + markCommitTimeOfFallback(); } if (supportsMutation && primaryChildParent !== null) { hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); } + if (enableSuspenseCallback && newState !== null) { + var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; + if (typeof suspenseCallback === "function") { + var thenables = finishedWork.updateQueue; + if (thenables !== null) { + suspenseCallback(new Set(thenables)); + } + } else { + if (suspenseCallback !== undefined) { + warning$1(false, "Unexpected type for suspenseCallback."); + } + } + } +} + +function attachSuspenseRetryListeners(finishedWork) { // If this boundary just timed out, then it will have a set of thenables. // For each thenable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. var thenables = finishedWork.updateQueue; if (thenables !== null) { finishedWork.updateQueue = null; @@ -15731,7 +18354,7 @@ var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, null); // Unmount the root by rendering null. update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property @@ -15746,7 +18369,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, null); update.tag = CaptureUpdate; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { @@ -15770,6 +18393,8 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // TODO: Warn in strict mode if getDerivedStateFromError is // not defined. markLegacyErrorBoundaryAsFailed(this); + + // Only log here if componentDidCatch is the only error boundary method defined logError(fiber, errorInfo); } var error = errorInfo.value; @@ -15854,12 +18479,19 @@ function throwException( // This is a thenable. var thenable = value; + checkForWrongSuspensePriorityInDEV(sourceFiber); + + 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) + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) ) { // Found the nearest boundary. @@ -15873,15 +18505,15 @@ function throwException( thenables.add(thenable); } - // If the boundary is outside of concurrent mode, we should *not* + // If the boundary is outside of batched 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 concurrent mode tree. If the Suspense is outside of it, we + // inside a batched mode tree. If the Suspense is outside of it, we // should *not* suspend the commit. - if ((_workInProgress.mode & ConcurrentMode) === NoContext) { + if ((_workInProgress.mode & BatchedMode) === NoMode) { _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete. @@ -15898,9 +18530,9 @@ function throwException( 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 updte to + // since it's known to be in an inconsistent state. Use a force update to // prevent a bail out. - var update = createUpdate(Sync); + var update = createUpdate(Sync, null); update.tag = ForceUpdate; enqueueUpdate(sourceFiber, update); } @@ -15916,11 +18548,51 @@ function throwException( // 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. SuspenseConfig applies 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. attachPingListener(root, renderExpirationTime, thenable); _workInProgress.effectTag |= ShouldCapture; _workInProgress.expirationTime = renderExpirationTime; + return; } else if ( enableSuspenseServerRenderer && @@ -15936,7 +18608,9 @@ function throwException( (function() { if (!current$$1) { throw ReactError( - "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React." + Error( + "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React." + ) ); } })(); @@ -16026,130 +18700,29 @@ function throwException( } while (workInProgress !== null); } -function unwindWork(workInProgress, renderExpirationTime) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; - if (isContextProvider(Component)) { - popContext(workInProgress); - } - var effectTag = workInProgress.effectTag; - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - return null; - } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; - (function() { - if (!((_effectTag & DidCapture) === NoEffect)) { - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - })(); - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; - } - case SuspenseComponent: { - var _effectTag2 = workInProgress.effectTag; - if (_effectTag2 & ShouldCapture) { - workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; - // Captured a suspense effect. Re-render the boundary. - return workInProgress; - } - return null; - } - case DehydratedSuspenseComponent: { - if (enableSuspenseServerRenderer) { - // TODO: popHydrationState - var _effectTag3 = workInProgress.effectTag; - if (_effectTag3 & ShouldCapture) { - workInProgress.effectTag = - (_effectTag3 & ~ShouldCapture) | DidCapture; - // Captured a suspense effect. Re-render the boundary. - return workInProgress; - } - } - return null; - } - case HostPortal: - popHostContainer(workInProgress); - return null; - case ContextProvider: - popProvider(workInProgress); - return null; - case EventComponent: - case EventTarget: - if (enableEventAPI) { - popHostContext(workInProgress); - } - return null; - default: - return null; - } -} - -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); - } - break; - } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - break; - } - case HostComponent: { - popHostContext(interruptedWork); - break; - } - case HostPortal: - popHostContainer(interruptedWork); - break; - case ContextProvider: - popProvider(interruptedWork); - break; - default: - break; - } -} - -// TODO: Ahaha Andrew is bad at spellling // DEV stuff var ceil = Math.ceil; var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; -var ReactShouldWarnActingUpdates = - ReactSharedInternals.ReactShouldWarnActingUpdates; +var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; -var NotWorking = 0; -var BatchedPhase = 1; -var LegacyUnbatchedPhase = 2; -var FlushSyncPhase = 3; -var RenderPhase = 4; -var CommitPhase = 5; +var NoContext = /* */ 0; +var BatchedContext = /* */ 1; +var EventContext = /* */ 2; +var DiscreteEventContext = /* */ 4; +var LegacyUnbatchedContext = /* */ 8; +var RenderContext = /* */ 16; +var CommitContext = /* */ 32; var RootIncomplete = 0; var RootErrored = 1; var RootSuspended = 2; -var RootCompleted = 3; +var RootSuspendedWithDelay = 3; +var RootCompleted = 4; -// The phase of work we're currently in -var workPhase = NotWorking; +// Describes where we are in the React execution stack +var executionContext = NoContext; // The root we're working on var workInProgressRoot = null; // The fiber we're working on @@ -16162,7 +18735,17 @@ var workInProgressRootExitStatus = RootIncomplete; // This is conceptually a time stamp but expressed in terms of an ExpirationTime // because we deal mostly with expiration times in the hot path, so this avoids // the conversion happening in the hot path. -var workInProgressRootMostRecentEventTime = Sync; +var workInProgressRootLatestProcessedExpirationTime = Sync; +var workInProgressRootLatestSuspenseTimeout = Sync; +var workInProgressRootCanSuspendUsingConfig = null; +// If we're pinged while rendering we don't always restart immediately. +// This flag determines if it might be worthwhile to restart if an opportunity +// happens latere. +var workInProgressRootHasPendingPing = false; +// 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; +var FALLBACK_THROTTLE_MS = 500; var nextEffect = null; var hasUncaughtError = false; @@ -16185,6 +18768,12 @@ var nestedPassiveUpdateCount = 0; var interruptedBy = null; +// Marks the need to reschedule pending interactions at these expiration times +// during the commit phase. This enables them to be traced across components +// that spawn new work during render. E.g. hidden boundaries, suspended SSR +// hydration or SuspenseList. +var spawnedWorkDuringRender = null; + // Expiration times are computed by adding to the current time (the start // time). However, if two updates are scheduled within the same event, we // should treat their start times as simultaneous, even if the actual clock @@ -16196,7 +18785,7 @@ var interruptedBy = null; var currentEventTime = NoWork; function requestCurrentTime() { - if (workPhase === RenderPhase || workPhase === CommitPhase) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { // We're inside React, so it's fine to read the actual time. return msToExpirationTime(now()); } @@ -16210,46 +18799,62 @@ function requestCurrentTime() { return currentEventTime; } -function computeExpirationForFiber(currentTime, fiber) { - if ((fiber.mode & ConcurrentMode) === NoContext) { +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + var mode = fiber.mode; + if ((mode & BatchedMode) === NoMode) { return Sync; } - if (workPhase === RenderPhase) { + var priorityLevel = getCurrentPriorityLevel(); + if ((mode & ConcurrentMode) === NoMode) { + return priorityLevel === ImmediatePriority ? Sync : Batched; + } + + if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering return renderExpirationTime; } - // Compute an expiration time based on the Scheduler priority. var expirationTime = void 0; - var priorityLevel = getCurrentPriorityLevel(); - switch (priorityLevel) { - case ImmediatePriority: - expirationTime = Sync; - break; - case UserBlockingPriority: - // TODO: Rename this to computeUserBlockingExpiration - expirationTime = computeInteractiveExpiration(currentTime); - break; - case NormalPriority: - case LowPriority: - // TODO: Handle LowPriority - // TODO: Rename this to... something better. - expirationTime = computeAsyncExpiration(currentTime); - break; - case IdlePriority: - expirationTime = Never; - break; - default: - (function() { - { - throw ReactError("Expected a valid priority level"); - } - })(); + if (suspenseConfig !== null) { + // Compute an expiration time based on the Suspense timeout. + expirationTime = computeSuspenseExpiration( + currentTime, + suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION + ); + } else { + // Compute an expiration time based on the Scheduler priority. + switch (priorityLevel) { + case ImmediatePriority: + expirationTime = Sync; + break; + case UserBlockingPriority$1: + // TODO: Rename this to computeUserBlockingExpiration + expirationTime = computeInteractiveExpiration(currentTime); + break; + case NormalPriority: + case LowPriority: + // TODO: Handle LowPriority + // TODO: Rename this to... something better. + expirationTime = computeAsyncExpiration(currentTime); + break; + case IdlePriority: + expirationTime = Never; + break; + default: + (function() { + { + throw ReactError(Error("Expected a valid priority level")); + } + })(); + } } // If we're in the middle of rendering a tree, do not update at the same // expiration time that is already rendering. + // TODO: We shouldn't have to do this if the update is on a different root. + // Refactor computeExpirationForFiber + scheduleUpdate so we have access to + // the root when we check for this condition. if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; @@ -16273,8 +18878,20 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { checkForInterruption(fiber, expirationTime); recordScheduleUpdate(); + // TODO: computeExpirationForFiber also reads the priority. Pass the + // priority as an argument to that function and this one. + var priorityLevel = getCurrentPriorityLevel(); + if (expirationTime === Sync) { - if (workPhase === LegacyUnbatchedPhase) { + if ( + // Check if we're inside unbatchedUpdates + (executionContext & LegacyUnbatchedContext) !== NoContext && + // Check if we're not already rendering + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + // Register pending interactions on the root to avoid losing traced interaction data. + schedulePendingInteractions(root, expirationTime); + // This is a legacy edge case. The initial mount of a ReactDOM.render-ed // root inside of batchedUpdates should be synchronous, but layout updates // should be deferred until the end of the batch. @@ -16284,35 +18901,36 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { } } else { scheduleCallbackForRoot(root, ImmediatePriority, Sync); - if (workPhase === NotWorking) { + if (executionContext === NoContext) { // Flush the synchronous work now, wnless we're already working or inside // a batch. This is intentionally inside scheduleUpdateOnFiber instead of // scheduleCallbackForFiber to preserve the ability to schedule a callback - // without immediately flushing it. We only do this for user-initated + // without immediately flushing it. We only do this for user-initiated // updates, to preserve historical behavior of sync mode. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } } else { - // TODO: computeExpirationForFiber also reads the priority. Pass the - // priority as an argument to that function and this one. - var priorityLevel = getCurrentPriorityLevel(); - if (priorityLevel === UserBlockingPriority) { - // This is the result of a discrete event. Track the lowest priority - // discrete update per root so we can flush them early, if needed. - if (rootsWithPendingDiscreteUpdates === null) { - rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); - } else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); - if ( - lastDiscreteTime === undefined || - lastDiscreteTime > expirationTime - ) { - rootsWithPendingDiscreteUpdates.set(root, expirationTime); - } + scheduleCallbackForRoot(root, priorityLevel, expirationTime); + } + + 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) + ) { + // This is the result of a discrete event. Track the lowest priority + // discrete update per root so we can flush them early, if needed. + if (rootsWithPendingDiscreteUpdates === null) { + rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); + } else { + var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); + if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) { + rootsWithPendingDiscreteUpdates.set(root, expirationTime); } } - scheduleCallbackForRoot(root, priorityLevel, expirationTime); } } var scheduleWork = scheduleUpdateOnFiber; @@ -16393,42 +19011,46 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { } root.callbackExpirationTime = expirationTime; - var options = null; - if (expirationTime !== Sync && expirationTime !== Never) { - var timeout = expirationTimeToMs(expirationTime) - now(); - if (timeout > 5000) { - // Sanity check. Should never take longer than 5 seconds. - // TODO: Add internal warning? - timeout = 5000; + if (expirationTime === Sync) { + // Sync React callbacks are scheduled on a special internal queue + root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + ); + } else { + var options = null; + if (expirationTime !== Never) { + var timeout = expirationTimeToMs(expirationTime) - now(); + options = { timeout: timeout }; + } + + root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + options + ); + if ( + enableUserTimingAPI && + expirationTime !== Sync && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + // Scheduled an async callback, and we're not already working. Add an + // entry to the flamegraph that shows we're waiting for a callback + // to fire. + startRequestCallbackTimer(); } - options = { timeout: timeout }; - } - - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - options - ); - if ( - enableUserTimingAPI && - expirationTime !== Sync && - workPhase !== RenderPhase && - workPhase !== CommitPhase - ) { - // Scheduled an async callback, and we're not already working. Add an - // entry to the flamegraph that shows we're waiting for a callback - // to fire. - startRequestCallbackTimer(); } } - // Add the current set of interactions to the pending set associated with - // this root. - schedulePendingInteraction(root, expirationTime); + // Associate the current interactions with this new root+priority. + schedulePendingInteractions(root, expirationTime); } function runRootCallback(root, callback, isSync) { @@ -16453,15 +19075,33 @@ function runRootCallback(root, callback, isSync) { } } -function flushInteractiveUpdates$1() { - if (workPhase === RenderPhase || workPhase === CommitPhase) { - // Can't synchronously flush interactive updates if React is already - // working. This is currently a no-op. - // TODO: Should we fire a warning? This happens if you synchronously invoke - // an input event inside an effect, like with `element.click()`. +function flushDiscreteUpdates() { + // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. + // However, `act` uses `batchedUpdates`, so there's no way to distinguish + // those two cases. Need to fix this before exposing flushDiscreteUpdates + // as a public API. + if ( + (executionContext & (BatchedContext | RenderContext | CommitContext)) !== + NoContext + ) { + if (true && (executionContext & RenderContext) !== NoContext) { + warning$1( + false, + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } + // We're already rendering, so we can't synchronously flush pending work. + // This is probably a nested event dispatch triggered by a lifecycle/effect, + // like `el.focus()`. Exit. return; } flushPendingDiscreteUpdates(); + if (!revertPassiveEffectsChange) { + // If the discrete updates scheduled passive effects, flush them now so that + // they fire before the next serial event. + flushPassiveEffects(); + } } function resolveLocksOnRoot(root, expirationTime) { @@ -16471,8 +19111,6 @@ function resolveLocksOnRoot(root, expirationTime) { firstBatch._defer && firstBatch._expirationTime >= expirationTime ) { - root.finishedWork = root.current.alternate; - root.pendingCommitExpirationTime = expirationTime; scheduleCallback(NormalPriority, function() { firstBatch._onComplete(); return null; @@ -16483,15 +19121,6 @@ function resolveLocksOnRoot(root, expirationTime) { } } -function interactiveUpdates$1(fn, a, b, c) { - if (workPhase === NotWorking) { - // TODO: Remove this call. Instead of doing this automatically, the caller - // should explicitly call flushInteractiveUpdates. - flushPendingDiscreteUpdates(); - } - return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); -} - function flushPendingDiscreteUpdates() { if (rootsWithPendingDiscreteUpdates !== null) { // For each root with pending discrete updates, schedule a callback to @@ -16499,56 +19128,84 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback( - ImmediatePriority, - renderRoot.bind(null, root, expirationTime) - ); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); // Now flush the immediate queue. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function batchedUpdates$1(fn, a) { - if (workPhase !== NotWorking) { - // We're already working, or inside a batch, so batchedUpdates is a no-op. + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + try { return fn(a); + } finally { + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } } - workPhase = BatchedPhase; +} + +function batchedEventUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= EventContext; try { return fn(a); } finally { - workPhase = NotWorking; - // Flush the immediate callbacks that were scheduled during this batch - flushImmediateQueue(); + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} + +function discreteUpdates$1(fn, a, b, c) { + var prevExecutionContext = executionContext; + executionContext |= DiscreteEventContext; + try { + // Should this + return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c)); + } finally { + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } } } function flushSync(fn, a) { - if (workPhase === RenderPhase || workPhase === CommitPhase) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { (function() { { throw ReactError( - "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." + Error( + "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." + ) ); } })(); } - var prevWorkPhase = workPhase; - workPhase = FlushSyncPhase; + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; try { - return runWithPriority(ImmediatePriority, fn.bind(null, a)); + return runWithPriority$1(ImmediatePriority, fn.bind(null, a)); } finally { - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up // the stack. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = NoWork; + root.finishedWork = null; + root.finishedExpirationTime = NoWork; var timeoutHandle = root.timeoutHandle; if (timeoutHandle !== noTimeout) { @@ -16570,17 +19227,26 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = Sync; + workInProgressRootLatestProcessedExpirationTime = Sync; + workInProgressRootLatestSuspenseTimeout = Sync; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = false; + + if (enableSchedulerTracing) { + spawnedWorkDuringRender = null; + } { ReactStrictModeWarnings.discardPendingWarnings(); + componentsThatSuspendedAtHighPri = null; + componentsThatTriggeredHighPriSuspend = null; } } function renderRoot(root, expirationTime, isSync) { (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Should not already be working."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError(Error("Should not already be working.")); } })(); @@ -16596,10 +19262,11 @@ function renderRoot(root, expirationTime, isSync) { return null; } - if (root.pendingCommitExpirationTime === expirationTime) { + if (isSync && root.finishedExpirationTime === expirationTime) { // There's already a pending commit at this expiration time. - root.pendingCommitExpirationTime = NoWork; - return commitRoot.bind(null, root, expirationTime); + // TODO: This is poorly factored. This case only exists for the + // batch.commit() API. + return commitRoot.bind(null, root); } flushPassiveEffects(); @@ -16608,14 +19275,34 @@ function renderRoot(root, expirationTime, isSync) { // and prepare a fresh one. Otherwise we'll continue where we left off. if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) { prepareFreshStack(root, expirationTime); - startWorkOnPendingInteraction(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) { + // We could've received an update at a lower priority while we yielded. + // We're suspended in a delayed state. Once we complete this render we're + // just going to try to recover at the last pending time anyway so we might + // as well start doing that eagerly. + // Ideally we should be able to do this even for retries but we don't yet + // know if we're going to process an update which wants to commit earlier, + // and this path happens very early so it would happen too often. Instead, + // for that case, we'll wait until we complete. + if (workInProgressRootHasPendingPing) { + // We have a ping at this expiration. Let's restart to see if we get unblocked. + prepareFreshStack(root, expirationTime); + } else { + var lastPendingTime = root.lastPendingTime; + if (lastPendingTime < expirationTime) { + // There's lower priority work. It might be unsuspended. Try rendering + // at that level immediately, while preserving the position in the queue. + return renderRoot.bind(null, root, lastPendingTime); + } + } } // If we have a work-in-progress fiber, it means there's still work to do // in this root. if (workInProgress !== null) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + var prevExecutionContext = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -16641,8 +19328,8 @@ function renderRoot(root, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) { // Restart at the current time. - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = prevExecutionContext; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; @@ -16666,7 +19353,7 @@ function renderRoot(root, expirationTime, isSync) { break; } catch (thrownValue) { // Reset module-level state that was set during the render phase. - resetContextDependences(); + resetContextDependencies(); resetHooks(); var sourceFiber = workInProgress; @@ -16676,7 +19363,7 @@ function renderRoot(root, expirationTime, isSync) { // supposed to capture all errors that weren't caught by an error // boundary. prepareFreshStack(root, expirationTime); - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; throw thrownValue; } @@ -16699,8 +19386,8 @@ function renderRoot(root, expirationTime, isSync) { } } while (true); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = prevExecutionContext; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; @@ -16720,6 +19407,9 @@ function renderRoot(root, expirationTime, isSync) { // something suspended, wait to commit it after a timeout. stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + var isLocked = resolveLocksOnRoot(root, expirationTime); if (isLocked) { // This root has a lock that prevents it from committing. Exit. If we begin @@ -16731,11 +19421,13 @@ function renderRoot(root, expirationTime, isSync) { // Set this to null to indicate there's no in-progress render. workInProgressRoot = null; + flushSuspensePriorityWarningInDEV(); + switch (workInProgressRootExitStatus) { case RootIncomplete: { (function() { { - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); } })(); } @@ -16745,77 +19437,192 @@ function renderRoot(root, expirationTime, isSync) { case RootErrored: { // An error was thrown. First check if there is lower priority work // scheduled on this root. - var lastPendingTime = root.lastPendingTime; - if (root.lastPendingTime < expirationTime) { + var _lastPendingTime = root.lastPendingTime; + if (_lastPendingTime < expirationTime) { // There's lower priority work. Before raising the error, try rendering // at the lower priority to see if it fixes it. Use a continuation to // maintain the existing priority and position in the queue. - return renderRoot.bind(null, root, lastPendingTime); + return renderRoot.bind(null, root, _lastPendingTime); } if (!isSync) { // If we're rendering asynchronously, it's possible the error was // caused by tearing due to a mutation during an event. Try rendering // one more time without yiedling to events. prepareFreshStack(root, expirationTime); - scheduleCallback( - ImmediatePriority, - renderRoot.bind(null, root, expirationTime) - ); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); return null; } // If we're already rendering synchronously, commit the root in its // errored state. - return commitRoot.bind(null, root, expirationTime); + return commitRoot.bind(null, root); } case RootSuspended: { + // We have an acceptable loading state. We need to figure out if we should + // immediately commit it or wait a bit. + + // If we have processed new updates during this render, we may now have a + // new loading state ready. We want to ensure that we commit that as soon as + // possible. + var hasNotProcessedNewUpdates = + workInProgressRootLatestProcessedExpirationTime === Sync; + if (hasNotProcessedNewUpdates && !isSync) { + // If we have not processed any new updates during this pass, then this is + // either a retry of an existing fallback state or a hidden tree. + // Hidden trees shouldn't be batched with other work and after that's + // fixed it can only be a retry. + // We're going to throttle committing retries so that we don't show too + // many loading states too quickly. + var msUntilTimeout = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); + // Don't bother with a very short suspense time. + if (msUntilTimeout > 10) { + if (workInProgressRootHasPendingPing) { + // This render was pinged but we didn't get to restart earlier so try + // restarting now instead. + prepareFreshStack(root, expirationTime); + return renderRoot.bind(null, root, expirationTime); + } + var _lastPendingTime2 = root.lastPendingTime; + if (_lastPendingTime2 < expirationTime) { + // There's lower priority work. It might be unsuspended. Try rendering + // at that level. + return renderRoot.bind(null, root, _lastPendingTime2); + } + // The render is suspended, it hasn't timed out, and there's no lower + // priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + msUntilTimeout + ); + return null; + } + } + // The work expired. Commit immediately. + return commitRoot.bind(null, root); + } + case RootSuspendedWithDelay: { if (!isSync) { - var _lastPendingTime = root.lastPendingTime; - if (root.lastPendingTime < expirationTime) { + // We're suspended in a state that should be avoided. We'll try to avoid committing + // it for as long as the timeouts let us. + if (workInProgressRootHasPendingPing) { + // This render was pinged but we didn't get to restart earlier so try + // restarting now instead. + prepareFreshStack(root, expirationTime); + return renderRoot.bind(null, root, expirationTime); + } + var _lastPendingTime3 = root.lastPendingTime; + if (_lastPendingTime3 < expirationTime) { // There's lower priority work. It might be unsuspended. Try rendering - // at that level. - return renderRoot.bind(null, root, _lastPendingTime); + // at that level immediately. + return renderRoot.bind(null, root, _lastPendingTime3); } - // If workInProgressRootMostRecentEventTime is Sync, that means we didn't - // track any event times. That can happen if we retried but nothing switched - // from fallback to content. There's no reason to delay doing no work. - if (workInProgressRootMostRecentEventTime !== Sync) { - var msUntilTimeout = computeMsUntilTimeout( - workInProgressRootMostRecentEventTime, - expirationTime + + var _msUntilTimeout = void 0; + if (workInProgressRootLatestSuspenseTimeout !== Sync) { + // We have processed a suspense config whose expiration time we can use as + // the timeout. + _msUntilTimeout = + expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now(); + } else if (workInProgressRootLatestProcessedExpirationTime === Sync) { + // This should never normally happen because only new updates cause + // delayed states, so we should have processed something. However, + // this could also happen in an offscreen tree. + _msUntilTimeout = 0; + } else { + // If we don't have a suspense config, we're going to use a heuristic to + var eventTimeMs = inferTimeFromExpirationTime( + workInProgressRootLatestProcessedExpirationTime ); - // Don't bother with a very short suspense time. - if (msUntilTimeout > 10) { - // The render is suspended, it hasn't timed out, and there's no lower - // priority work to do. Instead of committing the fallback - // immediately, wait for more data to arrive. - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, expirationTime), - msUntilTimeout - ); - return null; + var currentTimeMs = now(); + var timeUntilExpirationMs = + expirationTimeToMs(expirationTime) - currentTimeMs; + var timeElapsed = currentTimeMs - eventTimeMs; + if (timeElapsed < 0) { + // We get this wrong some time since we estimate the time. + timeElapsed = 0; } + + _msUntilTimeout = jnd(timeElapsed) - timeElapsed; + + // Clamp the timeout to the expiration time. + // TODO: Once the event time is exact instead of inferred from expiration time + // we don't need this. + if (timeUntilExpirationMs < _msUntilTimeout) { + _msUntilTimeout = timeUntilExpirationMs; + } + } + + // Don't bother with a very short suspense time. + if (_msUntilTimeout > 10) { + // The render is suspended, it hasn't timed out, and there's no lower + // priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + _msUntilTimeout + ); + return null; } } // The work expired. Commit immediately. - return commitRoot.bind(null, root, expirationTime); + return commitRoot.bind(null, root); } case RootCompleted: { // The work completed. Ready to commit. - return commitRoot.bind(null, root, expirationTime); + if ( + !isSync && + workInProgressRootLatestProcessedExpirationTime !== Sync && + workInProgressRootCanSuspendUsingConfig !== null + ) { + // If we have exceeded the minimum loading delay, which probably + // means we have shown a spinner already, we might have to suspend + // a bit longer to ensure that the spinner is shown for enough time. + var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay( + workInProgressRootLatestProcessedExpirationTime, + expirationTime, + workInProgressRootCanSuspendUsingConfig + ); + if (_msUntilTimeout2 > 10) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + _msUntilTimeout2 + ); + return null; + } + } + return commitRoot.bind(null, root); } default: { (function() { { - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } })(); } } } -function markRenderEventTime(expirationTime) { - if (expirationTime < workInProgressRootMostRecentEventTime) { - workInProgressRootMostRecentEventTime = expirationTime; +function markCommitTimeOfFallback() { + globalMostRecentFallbackTime = now(); +} + +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + if ( + expirationTime < workInProgressRootLatestProcessedExpirationTime && + expirationTime > Never + ) { + workInProgressRootLatestProcessedExpirationTime = expirationTime; + } + if (suspenseConfig !== null) { + if ( + expirationTime < workInProgressRootLatestSuspenseTimeout && + expirationTime > Never + ) { + workInProgressRootLatestSuspenseTimeout = expirationTime; + // Most of the time we only have one config and getting wrong is not bad. + workInProgressRootCanSuspendUsingConfig = suspenseConfig; + } } } @@ -16825,15 +19632,29 @@ function renderDidSuspend() { } } -function renderDidError() { +function renderDidSuspendDelayIfPossible() { if ( workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended ) { + workInProgressRootExitStatus = RootSuspendedWithDelay; + } +} + +function renderDidError() { + if (workInProgressRootExitStatus !== RootCompleted) { workInProgressRootExitStatus = RootErrored; } } +// Called during render to determine if anything has suspended. +// Returns false if we're not sure. +function renderHasNotSuspendedYet() { + // If something errored or completed, we can't really be sure, + // so those are false. + return workInProgressRootExitStatus === RootIncomplete; +} + function inferTimeFromExpirationTime(expirationTime) { // We don't know exactly when the update was scheduled, but we can infer an // approximate start time from the expiration time. @@ -16841,6 +19662,20 @@ function inferTimeFromExpirationTime(expirationTime) { return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION; } +function inferTimeFromExpirationTimeWithSuspenseConfig( + expirationTime, + suspenseConfig +) { + // We don't know exactly when the update was scheduled, but we can infer an + // approximate start time from the expiration time by subtracting the timeout + // that was added to the event time. + var earliestExpirationTimeMs = expirationTimeToMs(expirationTime); + return ( + earliestExpirationTimeMs - + (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) + ); +} + function workLoopSync() { // Already timed out, so perform work without checking if we need to yield. while (workInProgress !== null) { @@ -16865,7 +19700,7 @@ function performUnitOfWork(unitOfWork) { setCurrentFiber(unitOfWork); var next = void 0; - if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoContext) { + if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); @@ -16901,7 +19736,7 @@ function completeUnitOfWork(unitOfWork) { var next = void 0; if ( !enableProfilerTimer || - (workInProgress.mode & ProfileMode) === NoContext + (workInProgress.mode & ProfileMode) === NoMode ) { next = completeWork(current$$1, workInProgress, renderExpirationTime); } else { @@ -16967,7 +19802,7 @@ function completeUnitOfWork(unitOfWork) { if ( enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoContext + (workInProgress.mode & ProfileMode) !== NoMode ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); @@ -17031,7 +19866,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoContext) { + if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -17084,11 +19919,8 @@ function resetChildExpirationTime(completedWork) { completedWork.childExpirationTime = newChildExpirationTime; } -function commitRoot(root, expirationTime) { - runWithPriority( - ImmediatePriority, - commitRootImpl.bind(null, root, expirationTime) - ); +function commitRoot(root) { + runWithPriority$1(ImmediatePriority, commitRootImpl.bind(null, root)); // If there are passive effects, schedule a callback to flush them. This goes // outside commitRootImpl so that it inherits the priority of the render. if (rootWithPendingPassiveEffects !== null) { @@ -17101,19 +19933,31 @@ function commitRoot(root, expirationTime) { return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); flushRenderPhaseStrictModeWarningsInDEV(); (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Should not already be working."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError(Error("Should not already be working.")); } })(); - var finishedWork = root.current.alternate; + + var finishedWork = root.finishedWork; + var expirationTime = root.finishedExpirationTime; + if (finishedWork === null) { + return null; + } + root.finishedWork = null; + root.finishedExpirationTime = NoWork; + (function() { - if (!(finishedWork !== null)) { - throw ReactError("Should have a work-in-progress root."); + if (!(finishedWork !== root.current)) { + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); } })(); @@ -17169,8 +20013,8 @@ function commitRootImpl(root, expirationTime) { } if (firstEffect !== null) { - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + var prevExecutionContext = executionContext; + executionContext |= CommitContext; var prevInteractions = null; if (enableSchedulerTracing) { prevInteractions = tracing.__interactionsRef.current; @@ -17196,7 +20040,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var error = clearCaughtError(); @@ -17222,7 +20066,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var _error = clearCaughtError(); @@ -17257,7 +20101,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var _error2 = clearCaughtError(); @@ -17270,10 +20114,14 @@ function commitRootImpl(root, expirationTime) { nextEffect = null; + // Tell Scheduler to yield at the end of the frame, so the browser has an + // opportunity to paint. + requestPaint(); + if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; } - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; } else { // No effects. root.current = finishedWork; @@ -17293,6 +20141,8 @@ function commitRootImpl(root, expirationTime) { stopCommitTimer(); + var rootDidHavePassiveEffects = rootDoesHavePassiveEffects; + if (rootDoesHavePassiveEffects) { // This commit has passive effects. Stash a reference to them. But don't // schedule a callback until after flushing layout work. @@ -17300,11 +20150,14 @@ function commitRootImpl(root, expirationTime) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsExpirationTime = expirationTime; } else { - if (enableSchedulerTracing) { - // If there are no passive effects, then we can complete the pending - // interactions. Otherwise, we'll wait until after the passive effects - // are flushed. - finishPendingInteractions(root, expirationTime); + // 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; + nextEffect = nextNextEffect; } } @@ -17316,6 +20169,21 @@ function commitRootImpl(root, expirationTime) { currentTime, remainingExpirationTime ); + + if (enableSchedulerTracing) { + if (spawnedWorkDuringRender !== null) { + var expirationTimes = spawnedWorkDuringRender; + spawnedWorkDuringRender = null; + for (var i = 0; i < expirationTimes.length; i++) { + scheduleInteractions( + root, + expirationTimes[i], + root.memoizedInteractions + ); + } + } + } + scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime); } else { // If there's no remaining work, we can clear the set of already failed @@ -17323,7 +20191,17 @@ function commitRootImpl(root, expirationTime) { legacyErrorBoundariesThatAlreadyFailed = null; } - onCommitRoot(finishedWork.stateNode); + if (enableSchedulerTracing) { + if (!rootDidHavePassiveEffects) { + // If there are no passive effects, then we can complete the pending interactions. + // Otherwise, we'll wait until after the passive effects are flushed. + // Wait to do this until after remaining work has been scheduled, + // so that we don't prematurely signal complete for interactions when there's e.g. hidden work. + finishPendingInteractions(root, expirationTime); + } + } + + onCommitRoot(finishedWork.stateNode, expirationTime); if (remainingExpirationTime === Sync) { // Count the number of times the root synchronously re-renders without @@ -17345,7 +20223,7 @@ function commitRootImpl(root, expirationTime) { throw _error3; } - if (workPhase === LegacyUnbatchedPhase) { + if ((executionContext & LegacyUnbatchedContext) !== NoContext) { // This is a legacy edge case. We just committed the initial mount of // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired // synchronously, but layout updates should be deferred until the end @@ -17354,7 +20232,7 @@ function commitRootImpl(root, expirationTime) { } // If layout work was scheduled, flush it now. - flushImmediateQueue(); + flushSyncCallbackQueue(); return null; } @@ -17480,12 +20358,14 @@ function flushPassiveEffects() { } (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Cannot flush passive effects while already rendering."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); } })(); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + var prevExecutionContext = executionContext; + executionContext |= CommitContext; // 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 @@ -17498,7 +20378,7 @@ function flushPassiveEffects() { if (hasCaughtError()) { (function() { if (!(effect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var error = clearCaughtError(); @@ -17506,7 +20386,10 @@ function flushPassiveEffects() { } resetCurrentFiber(); } - effect = effect.nextEffect; + var nextNextEffect = effect.nextEffect; + // Remove nextEffect pointer to assist GC + effect.nextEffect = null; + effect = nextNextEffect; } if (enableSchedulerTracing) { @@ -17514,8 +20397,8 @@ function flushPassiveEffects() { finishPendingInteractions(root, expirationTime); } - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. @@ -17608,9 +20491,32 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { // Received a ping at the same priority level at which we're currently - // rendering. Restart from the root. Don't need to schedule a ping because - // we're already working on this tree. - prepareFreshStack(root, renderExpirationTime); + // rendering. We might want to restart this render. This should mirror + // the logic of whether or not a root suspends once it completes. + + // TODO: If we're rendering sync either due to Sync, Batched or expired, + // we should probably never restart. + + // If we're suspended with delay, we'll always suspend so we can always + // restart. If we're suspended without any updates, it might be a retry. + // If it's early in the retry we can restart. We can't know for sure + // whether we'll eventually process an update during this render pass, + // but it's somewhat unlikely that we get to a ping before that, since + // getting to the root most update is usually very fast. + if ( + workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + workInProgressRootLatestProcessedExpirationTime === Sync && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ) { + // Restart from the root. Don't need to schedule a ping because + // we're already working on this tree. + prepareFreshStack(root, renderExpirationTime); + } else { + // Even though we can't restart right now, we might get an + // opportunity later. So we mark this render as having a ping. + workInProgressRootHasPendingPing = true; + } return; } @@ -17629,6 +20535,12 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { // Mark the time at which this ping was scheduled. root.pingTime = suspendedTime; + if (root.finishedExpirationTime === suspendedTime) { + // If there's a pending fallback waiting to commit, throw it away. + root.finishedExpirationTime = NoWork; + root.finishedWork = null; + } + var currentTime = requestCurrentTime(); var priorityLevel = inferPriorityFromExpirationTime( currentTime, @@ -17638,12 +20550,17 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { } function retryTimedOutBoundary(boundaryFiber) { - // The boundary fiber (a Suspense component) previously timed out and was - // rendered in its fallback state. One of the promises that suspended it has - // resolved, which means at least part of the tree was likely unblocked. Try - // rendering again, at a new expiration time. + // The boundary fiber (a Suspense component or SuspenseList component) + // previously was rendered in its fallback state. One of the promises that + // suspended it has resolved, which means at least part of the tree was + // likely unblocked. Try rendering again, at a new expiration time. var currentTime = requestCurrentTime(); - var retryTime = computeExpirationForFiber(currentTime, boundaryFiber); + var suspenseConfig = null; // Retries don't carry over the already committed update. + var retryTime = computeExpirationForFiber( + currentTime, + boundaryFiber, + suspenseConfig + ); // TODO: Special case idle priority? var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime); var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime); @@ -17666,7 +20583,9 @@ function resolveRetryThenable(boundaryFiber, thenable) { (function() { { throw ReactError( - "Pinged unknown suspense boundary type. This is probably a bug in React." + Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ) ); } })(); @@ -17709,29 +20628,30 @@ function jnd(timeElapsed) { : ceil(timeElapsed / 1960) * 1960; } -function computeMsUntilTimeout(mostRecentEventTime, committedExpirationTime) { - if (disableYielding) { - // Timeout immediately when yielding is disabled. +function computeMsUntilSuspenseLoadingDelay( + mostRecentEventTime, + committedExpirationTime, + suspenseConfig +) { + var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0; + if (busyMinDurationMs <= 0) { return 0; } + var busyDelayMs = suspenseConfig.busyDelayMs | 0; - var eventTimeMs = inferTimeFromExpirationTime(mostRecentEventTime); + // Compute the time until this render pass would expire. var currentTimeMs = now(); + var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig( + mostRecentEventTime, + suspenseConfig + ); var timeElapsed = currentTimeMs - eventTimeMs; - - var msUntilTimeout = jnd(timeElapsed) - timeElapsed; - - // Compute the time until this render pass would expire. - var timeUntilExpirationMs = - expirationTimeToMs(committedExpirationTime) - currentTimeMs; - - // Clamp the timeout to the expiration time. - // TODO: Once the event time is exact instead of inferred from expiration time - // we don't need this. - if (timeUntilExpirationMs < msUntilTimeout) { - msUntilTimeout = timeUntilExpirationMs; + if (timeElapsed <= busyDelayMs) { + // If we haven't yet waited longer than the initial delay, we don't + // have to wait any additional time. + return 0; } - + var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`. return msUntilTimeout; } @@ -17743,7 +20663,9 @@ function checkForNestedUpdates() { (function() { { throw ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) ); } })(); @@ -17765,11 +20687,10 @@ function checkForNestedUpdates() { function flushRenderPhaseStrictModeWarningsInDEV() { { - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); ReactStrictModeWarnings.flushLegacyContextWarning(); if (warnAboutDeprecatedLifecycles) { - ReactStrictModeWarnings.flushPendingDeprecationWarnings(); + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } } @@ -17864,7 +20785,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // Keep this code in sync with renderRoot; any changes here must have // corresponding changes there. - resetContextDependences(); + resetContextDependencies(); resetHooks(); // Unwind the failed stack frame @@ -17936,578 +20857,502 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { } } -function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { - { - if ( - workPhase === NotWorking && - ReactShouldWarnActingUpdates.current === false - ) { - warningWithoutStack$1( - false, - "An update to %s inside a test was not wrapped in act(...).\n\n" + - "When testing, code that causes React state updates should be " + - "wrapped into act(...):\n\n" + - "act(() => {\n" + - " /* fire events that update state */\n" + - "});\n" + - "/* assert on the output */\n\n" + - "This ensures that you're testing the behavior the user would see " + - "in the browser." + - " Learn more at https://fb.me/react-wrap-tests-with-act" + - "%s", - getComponentName(fiber.type), - getStackByFiberInDevAndProd(fiber) - ); - } - } -} - -var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; - -function computeThreadID(root, expirationTime) { - // Interaction threads are unique per root and expiration time. - return expirationTime * 1000 + root.interactionThreadID; -} - -function schedulePendingInteraction(root, expirationTime) { - // This is called when work is scheduled on a root. It sets up a pending - // interaction, which is completed once the work commits. - if (!enableSchedulerTracing) { - return; - } - - var interactions = tracing.__interactionsRef.current; - if (interactions.size > 0) { - var pendingInteractionMap = root.pendingInteractionMap; - var pendingInteractions = pendingInteractionMap.get(expirationTime); - if (pendingInteractions != null) { - interactions.forEach(function(interaction) { - if (!pendingInteractions.has(interaction)) { - // Update the pending async work count for previously unscheduled interaction. - interaction.__count++; - } - - pendingInteractions.add(interaction); - }); - } else { - pendingInteractionMap.set(expirationTime, new Set(interactions)); - - // Update the pending async work count for the current interactions. - interactions.forEach(function(interaction) { - interaction.__count++; - }); - } - - var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { - var threadID = computeThreadID(root, expirationTime); - subscriber.onWorkScheduled(interactions, threadID); - } - } -} - -function startWorkOnPendingInteraction(root, expirationTime) { - // This is called when new work is started on a root. - if (!enableSchedulerTracing) { - return; - } - - // Determine which interactions this batch of work currently includes, So that - // we can accurately attribute time spent working on it, And so that cascading - // work triggered during the render phase will be associated with it. - var interactions = new Set(); - root.pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledExpirationTime - ) { - if (scheduledExpirationTime >= expirationTime) { - scheduledInteractions.forEach(function(interaction) { - return interactions.add(interaction); - }); - } - }); - - // Store the current set of interactions on the FiberRoot for a few reasons: - // We can re-use it in hot functions like renderRoot() without having to - // recalculate it. We will also use it in commitWork() to pass to any Profiler - // onRender() hooks. This also provides DevTools with a way to access it when - // the onCommitRoot() hook is called. - root.memoizedInteractions = interactions; - - if (interactions.size > 0) { - var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { - var threadID = computeThreadID(root, expirationTime); - try { - subscriber.onWorkStarted(interactions, threadID); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } - } - } -} - -function finishPendingInteractions(root, committedExpirationTime) { - if (!enableSchedulerTracing) { - return; - } - - var earliestRemainingTimeAfterCommit = root.firstPendingTime; - - var subscriber = void 0; +var IsThisRendererActing = { current: false }; - try { - subscriber = tracing.__subscriberRef.current; - if (subscriber !== null && root.memoizedInteractions.size > 0) { - var threadID = computeThreadID(root, committedExpirationTime); - subscriber.onWorkStopped(root.memoizedInteractions, threadID); - } - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } finally { - // Clear completed interactions from the pending Map. - // Unless the render was suspended or cascading work was scheduled, - // In which case– leave pending interactions until the subsequent render. - var pendingInteractionMap = root.pendingInteractionMap; - pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledExpirationTime +function warnIfNotScopedWithMatchingAct(fiber) { + { + if ( + warnsIfNotActing === true && + IsSomeRendererActing.current === true && + IsThisRendererActing.current !== true ) { - // Only decrement the pending interaction count if we're done. - // If there's still work at the current priority, - // That indicates that we are waiting for suspense data. - if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { - pendingInteractionMap.delete(scheduledExpirationTime); - - scheduledInteractions.forEach(function(interaction) { - interaction.__count--; - - if (subscriber !== null && interaction.__count === 0) { - try { - subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } - } - }); - } - }); + warningWithoutStack$1( + false, + "It looks like you're using the wrong act() around your test interactions.\n" + + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + + "// for react-dom:\n" + + "import {act} from 'react-dom/test-utils';\n" + + "//...\n" + + "act(() => ...);\n\n" + + "// for react-test-renderer:\n" + + "import TestRenderer from 'react-test-renderer';\n" + + "const {act} = TestRenderer;\n" + + "//...\n" + + "act(() => ...);" + + "%s", + getStackByFiberInDevAndProd(fiber) + ); + } } } -// Resolves type to a family. - -// Used by React Refresh runtime through DevTools Global Hook. - -var resolveFamily = null; -// $FlowFixMe Flow gets confused by a WeakSet feature check below. -var failedBoundaries = null; - -var setRefreshHandler = function(handler) { +function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { - resolveFamily = handler; + if ( + warnsIfNotActing === true && + (fiber.mode & StrictMode) !== NoMode && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); + } } -}; +} -function resolveFunctionForHotReloading(type) { +function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return type; - } - var family = resolveFamily(type); - if (family === undefined) { - return type; + if ( + warnsIfNotActing === true && + executionContext === NoContext && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s inside a test was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); } - // Use the latest known implementation. - return family.current; } } -function resolveClassForHotReloading(type) { - // No implementation differences. - return resolveFunctionForHotReloading(type); -} +var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; -function resolveForwardRefForHotReloading(type) { +var componentsThatSuspendedAtHighPri = null; +var componentsThatTriggeredHighPriSuspend = null; +function checkForWrongSuspensePriorityInDEV(sourceFiber) { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return type; - } - var family = resolveFamily(type); - if (family === undefined) { - // Check if we're dealing with a real forwardRef. Don't want to crash early. - if ( - type !== null && - type !== undefined && - typeof type.render === "function" - ) { - // ForwardRef is special because its resolved .type is an object, - // but it's possible that we only have its inner render function in the map. - // If that inner render function is different, we'll build a new forwardRef type. - var currentRender = resolveFunctionForHotReloading(type.render); - if (type.render !== currentRender) { - var syntheticType = { - $$typeof: REACT_FORWARD_REF_TYPE, - render: currentRender - }; - if (type.displayName !== undefined) { - syntheticType.displayName = type.displayName; + var currentPriorityLevel = getCurrentPriorityLevel(); + if ( + (sourceFiber.mode & ConcurrentMode) !== NoEffect && + (currentPriorityLevel === UserBlockingPriority$1 || + currentPriorityLevel === ImmediatePriority) + ) { + var workInProgressNode = sourceFiber; + while (workInProgressNode !== null) { + // Add the component that triggered the suspense + var current$$1 = workInProgressNode.alternate; + if (current$$1 !== null) { + // TODO: warn component that triggers the high priority + // suspend is the HostRoot + switch (workInProgressNode.tag) { + case ClassComponent: + // Loop through the component's update queue and see whether the component + // has triggered any high priority updates + var updateQueue = current$$1.updateQueue; + if (updateQueue !== null) { + var update = updateQueue.firstUpdate; + while (update !== null) { + var priorityLevel = update.priority; + if ( + priorityLevel === UserBlockingPriority$1 || + priorityLevel === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + break; + } + update = update.next; + } + } + break; + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if ( + workInProgressNode.memoizedState !== null && + workInProgressNode.memoizedState.baseUpdate !== null + ) { + var _update = workInProgressNode.memoizedState.baseUpdate; + // Loop through the functional component's memoized state to see whether + // the component has triggered any high pri updates + while (_update !== null) { + var priority = _update.priority; + if ( + priority === UserBlockingPriority$1 || + priority === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + break; + } + if ( + _update.next === workInProgressNode.memoizedState.baseUpdate + ) { + break; + } + _update = _update.next; + } + } + break; + default: + break; } - return syntheticType; } + workInProgressNode = workInProgressNode.return; + } + + // Add the component name to a set. + var componentName = getComponentName(sourceFiber.type); + if (componentsThatSuspendedAtHighPri === null) { + componentsThatSuspendedAtHighPri = new Set([componentName]); + } else { + componentsThatSuspendedAtHighPri.add(componentName); } - return type; } - // Use the latest known implementation. - return family.current; } } -function isCompatibleFamilyForHotReloading(fiber, element) { +function flushSuspensePriorityWarningInDEV() { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return false; - } - - var prevType = fiber.elementType; - var nextType = element.type; - - // If we got here, we know types aren't === equal. - var needsCompareFamilies = false; - - var $$typeofNextType = - typeof nextType === "object" && nextType !== null - ? nextType.$$typeof - : null; + if (componentsThatSuspendedAtHighPri !== null) { + var componentNames = []; + componentsThatSuspendedAtHighPri.forEach(function(name) { + componentNames.push(name); + }); + componentsThatSuspendedAtHighPri = null; - switch (fiber.tag) { - case ClassComponent: { - if (typeof nextType === "function") { - needsCompareFamilies = true; - } - break; - } - case FunctionComponent: { - if (typeof nextType === "function") { - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - // We don't know the inner type yet. - // We're going to assume that the lazy inner type is stable, - // and so it is sufficient to avoid reconciling it away. - // We're not going to unwrap or actually use the new lazy type. - needsCompareFamilies = true; - } - break; - } - case ForwardRef: { - if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - needsCompareFamilies = true; - } - break; - } - case MemoComponent: - case SimpleMemoComponent: { - if ($$typeofNextType === REACT_MEMO_TYPE) { - // TODO: if it was but can no longer be simple, - // we shouldn't set this. - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - needsCompareFamilies = true; - } - break; + var componentsThatTriggeredSuspendNames = []; + if (componentsThatTriggeredHighPriSuspend !== null) { + componentsThatTriggeredHighPriSuspend.forEach(function(name) { + return componentsThatTriggeredSuspendNames.push(name); + }); } - default: - return false; - } - // Check if both types have a family and it's the same one. - if (needsCompareFamilies) { - // Note: memo() and forwardRef() we'll compare outer rather than inner type. - // This means both of them need to be registered to preserve state. - // If we unwrapped and compared the inner types for wrappers instead, - // then we would risk falsely saying two separate memo(Foo) - // calls are equivalent because they wrap the same Foo function. - var prevFamily = resolveFamily(prevType); - if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { - return true; + componentsThatTriggeredHighPriSuspend = null; + + var componentNamesString = componentNames.sort().join(", "); + var componentThatTriggeredSuspenseError = ""; + if (componentsThatTriggeredSuspendNames.length > 0) { + componentThatTriggeredSuspenseError = + "The following components triggered a user-blocking update:" + + "\n\n" + + " " + + componentsThatTriggeredSuspendNames.sort().join(", ") + + "\n\n" + + "that was then suspended by:" + + "\n\n" + + " " + + componentNamesString; + } else { + componentThatTriggeredSuspenseError = + "A user-blocking update was suspended by:" + + "\n\n" + + " " + + componentNamesString; } + + warningWithoutStack$1( + false, + "%s" + + "\n\n" + + "The fix is to split the update into multiple parts: a user-blocking " + + "update to provide immediate feedback, and another update that " + + "triggers the bulk of the changes." + + "\n\n" + + "Refer to the documentation for useSuspenseTransition to learn how " + + "to implement this pattern.", + // TODO: Add link to React docs with more information, once it exists + componentThatTriggeredSuspenseError + ); } - return false; } } -function markFailedErrorBoundaryForHotReloading(fiber) { - { - if (resolveFamily === null) { - // Hot reloading is disabled. - return; - } - if (typeof WeakSet !== "function") { - return; - } - if (failedBoundaries === null) { - failedBoundaries = new WeakSet(); - } - failedBoundaries.add(fiber); +function computeThreadID(root, expirationTime) { + // Interaction threads are unique per root and expiration time. + return expirationTime * 1000 + root.interactionThreadID; +} + +function markSpawnedWork(expirationTime) { + if (!enableSchedulerTracing) { + return; + } + if (spawnedWorkDuringRender === null) { + spawnedWorkDuringRender = [expirationTime]; + } else { + spawnedWorkDuringRender.push(expirationTime); } } -var scheduleRefresh = function(root, update) { - { - if (resolveFamily === null) { - // Hot reloading is disabled. - return; +function scheduleInteractions(root, expirationTime, interactions) { + if (!enableSchedulerTracing) { + return; + } + + if (interactions.size > 0) { + var pendingInteractionMap = root.pendingInteractionMap; + var pendingInteractions = pendingInteractionMap.get(expirationTime); + if (pendingInteractions != null) { + interactions.forEach(function(interaction) { + if (!pendingInteractions.has(interaction)) { + // Update the pending async work count for previously unscheduled interaction. + interaction.__count++; + } + + pendingInteractions.add(interaction); + }); + } else { + pendingInteractionMap.set(expirationTime, new Set(interactions)); + + // Update the pending async work count for the current interactions. + interactions.forEach(function(interaction) { + interaction.__count++; + }); } - var _staleFamilies = update.staleFamilies, - _updatedFamilies = update.updatedFamilies; - flushPassiveEffects(); - flushSync(function() { - scheduleFibersWithFamiliesRecursively( - root.current, - _updatedFamilies, - _staleFamilies - ); - }); + var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { + var threadID = computeThreadID(root, expirationTime); + subscriber.onWorkScheduled(interactions, threadID); + } } -}; +} -var scheduleRoot = function(root, element) { - { - if (root.context !== emptyContextObject) { - // Super edge case: root has a legacy _renderSubtree context - // but we don't know the parentComponent so we can't pass it. - // Just ignore. We'll delete this with _renderSubtree code path later. - return; - } - flushPassiveEffects(); - updateContainerAtExpirationTime(element, root, null, Sync, null); +function schedulePendingInteractions(root, expirationTime) { + // This is called when work is scheduled on a root. + // It associates the current interactions with the newly-scheduled expiration. + // They will be restored when that expiration is later committed. + if (!enableSchedulerTracing) { + return; } -}; -function scheduleFibersWithFamiliesRecursively( - fiber, - updatedFamilies, - staleFamilies -) { - { - var alternate = fiber.alternate, - child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type; + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); +} - var candidateType = null; - switch (tag) { - case FunctionComponent: - case SimpleMemoComponent: - case ClassComponent: - candidateType = type; - break; - case ForwardRef: - candidateType = type.render; - break; - default: - break; - } +function startWorkOnPendingInteractions(root, expirationTime) { + // This is called when new work is started on a root. + if (!enableSchedulerTracing) { + return; + } - if (resolveFamily === null) { - throw new Error("Expected resolveFamily to be set during hot reload."); + // Determine which interactions this batch of work currently includes, So that + // we can accurately attribute time spent working on it, And so that cascading + // work triggered during the render phase will be associated with it. + var interactions = new Set(); + root.pendingInteractionMap.forEach(function( + scheduledInteractions, + scheduledExpirationTime + ) { + if (scheduledExpirationTime >= expirationTime) { + scheduledInteractions.forEach(function(interaction) { + return interactions.add(interaction); + }); } + }); - var needsRender = false; - var needsRemount = false; - if (candidateType !== null) { - var family = resolveFamily(candidateType); - if (family !== undefined) { - if (staleFamilies.has(family)) { - needsRemount = true; - } else if (updatedFamilies.has(family)) { - needsRender = true; - } - } - } - if (failedBoundaries !== null) { - if ( - failedBoundaries.has(fiber) || - (alternate !== null && failedBoundaries.has(alternate)) - ) { - needsRemount = true; - } - } + // Store the current set of interactions on the FiberRoot for a few reasons: + // We can re-use it in hot functions like renderRoot() without having to + // recalculate it. We will also use it in commitWork() to pass to any Profiler + // onRender() hooks. This also provides DevTools with a way to access it when + // the onCommitRoot() hook is called. + root.memoizedInteractions = interactions; - if (needsRemount) { - fiber._debugNeedsRemount = true; - } - if (needsRemount || needsRender) { - scheduleWork(fiber, Sync); - } - if (child !== null && !needsRemount) { - scheduleFibersWithFamiliesRecursively( - child, - updatedFamilies, - staleFamilies - ); - } - if (sibling !== null) { - scheduleFibersWithFamiliesRecursively( - sibling, - updatedFamilies, - staleFamilies - ); + if (interactions.size > 0) { + var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { + var threadID = computeThreadID(root, expirationTime); + try { + subscriber.onWorkStarted(interactions, threadID); + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } } } } -var findHostInstancesForRefresh = function(root, families) { - { - var hostInstances = new Set(); - var types = new Set( - families.map(function(family) { - return family.current; - }) - ); - findHostInstancesForMatchingFibersRecursively( - root.current, - types, - hostInstances - ); - return hostInstances; +function finishPendingInteractions(root, committedExpirationTime) { + if (!enableSchedulerTracing) { + return; } -}; -function findHostInstancesForMatchingFibersRecursively( - fiber, - types, - hostInstances -) { - { - var child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type; + var earliestRemainingTimeAfterCommit = root.firstPendingTime; - var candidateType = null; - switch (tag) { - case FunctionComponent: - case SimpleMemoComponent: - case ClassComponent: - candidateType = type; - break; - case ForwardRef: - candidateType = type.render; - break; - default: - break; - } + var subscriber = void 0; - var didMatch = false; - if (candidateType !== null) { - if (types.has(candidateType)) { - didMatch = true; - } + try { + subscriber = tracing.__subscriberRef.current; + if (subscriber !== null && root.memoizedInteractions.size > 0) { + var threadID = computeThreadID(root, committedExpirationTime); + subscriber.onWorkStopped(root.memoizedInteractions, threadID); } + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } finally { + // Clear completed interactions from the pending Map. + // Unless the render was suspended or cascading work was scheduled, + // In which case– leave pending interactions until the subsequent render. + var pendingInteractionMap = root.pendingInteractionMap; + pendingInteractionMap.forEach(function( + scheduledInteractions, + scheduledExpirationTime + ) { + // Only decrement the pending interaction count if we're done. + // If there's still work at the current priority, + // That indicates that we are waiting for suspense data. + if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { + pendingInteractionMap.delete(scheduledExpirationTime); - if (didMatch) { - // We have a match. This only drills down to the closest host components. - // There's no need to search deeper because for the purpose of giving - // visual feedback, "flashing" outermost parent rectangles is sufficient. - findHostInstancesForFiberShallowly(fiber, hostInstances); - } else { - // If there's no match, maybe there will be one further down in the child tree. - if (child !== null) { - findHostInstancesForMatchingFibersRecursively( - child, - types, - hostInstances - ); + scheduledInteractions.forEach(function(interaction) { + interaction.__count--; + + if (subscriber !== null && interaction.__count === 0) { + try { + subscriber.onInteractionScheduledWorkCompleted(interaction); + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } + } + }); } - } - - if (sibling !== null) { - findHostInstancesForMatchingFibersRecursively( - sibling, - types, - hostInstances - ); - } + }); } } -function findHostInstancesForFiberShallowly(fiber, hostInstances) { - { - var foundHostInstances = findChildHostInstancesForFiberShallowly( - fiber, - hostInstances - ); - if (foundHostInstances) { - return; +var onCommitFiberRoot = null; +var onCommitFiberUnmount = 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; + } + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + 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) { + { + warningWithoutStack$1( + false, + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://fb.me/react-devtools" + ); } - // If we didn't find any host children, fallback to closest host parent. - var node = fiber; - while (true) { - switch (node.tag) { - case HostComponent: - hostInstances.add(node.stateNode); - return; - case HostPortal: - hostInstances.add(node.stateNode.containerInfo); - return; - case HostRoot: - hostInstances.add(node.stateNode.containerInfo); - return; + // DevTools exists, even though it doesn't support Fiber. + return true; + } + try { + var rendererID = hook.inject(internals); + // We have successfully injected, so now it is safe to set up hooks. + onCommitFiberRoot = function(root, expirationTime) { + try { + var didError = (root.current.effectTag & DidCapture) === DidCapture; + if (enableProfilerTimer) { + var currentTime = requestCurrentTime(); + var priorityLevel = inferPriorityFromExpirationTime( + currentTime, + expirationTime + ); + hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); + } else { + hook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); + } } - if (node.return === null) { - throw new Error("Expected to reach root first."); + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); + } } - node = node.return; + }; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s.", + err + ); } } + // DevTools exists + return true; } -function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { - { - var node = fiber; - var foundHostInstances = false; - while (true) { - if (node.tag === HostComponent) { - // We got a match. - foundHostInstances = true; - hostInstances.add(node.stateNode); - // There may still be more, so keep searching. - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - if (node === fiber) { - return foundHostInstances; - } - while (node.sibling === null) { - if (node.return === null || node.return === fiber) { - return foundHostInstances; - } - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } +function onCommitRoot(root, expirationTime) { + if (typeof onCommitFiberRoot === "function") { + onCommitFiberRoot(root, expirationTime); + } +} + +function onCommitUnmount(fiber) { + if (typeof onCommitFiberUnmount === "function") { + onCommitFiberUnmount(fiber); } - return false; } var hasBadMapPolyfill = void 0; @@ -18558,7 +21403,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.memoizedProps = null; this.updateQueue = null; this.memoizedState = null; - this.contextDependencies = null; + this.dependencies = null; this.mode = mode; @@ -18718,7 +21563,19 @@ function createWorkInProgress(current, pendingProps, expirationTime) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + + // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + expirationTime: currentDependencies.expirationTime, + firstContext: currentDependencies.firstContext, + listeners: currentDependencies.listeners, + responders: currentDependencies.responders + }; // These will be overridden during the parent's reconciliation workInProgress.sibling = current.sibling; @@ -18752,8 +21609,87 @@ function createWorkInProgress(current, pendingProps, expirationTime) { return workInProgress; } -function createHostRootFiber(isConcurrent) { - var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext; +// Used to reuse a Fiber for a second pass. +function resetWorkInProgress(workInProgress, renderExpirationTime) { + // This resets the Fiber to what createFiber or createWorkInProgress would + // have set the values to before during the first pass. Ideally this wouldn't + // be necessary but unfortunately many code paths reads from the workInProgress + // 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 + // that child fiber is setting, not the reconciliation. + workInProgress.effectTag &= Placement; + + // The effect list is no longer valid. + workInProgress.nextEffect = null; + workInProgress.firstEffect = null; + workInProgress.lastEffect = null; + + var current = workInProgress.alternate; + if (current === null) { + // Reset to createFiber's initial values. + workInProgress.childExpirationTime = NoWork; + workInProgress.expirationTime = renderExpirationTime; + + workInProgress.child = null; + workInProgress.memoizedProps = null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + + workInProgress.dependencies = null; + + if (enableProfilerTimer) { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = 0; + workInProgress.treeBaseDuration = 0; + } + } else { + // Reset to the cloned values that createWorkInProgress would've. + workInProgress.childExpirationTime = current.childExpirationTime; + workInProgress.expirationTime = current.expirationTime; + + workInProgress.child = current.child; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; + + // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + expirationTime: currentDependencies.expirationTime, + firstContext: currentDependencies.firstContext, + listeners: currentDependencies.listeners, + responders: currentDependencies.responders + }; + + if (enableProfilerTimer) { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; + } + } + + return workInProgress; +} + +function createHostRootFiber(tag) { + var mode = void 0; + if (tag === ConcurrentRoot) { + mode = ConcurrentMode | BatchedMode | StrictMode; + } else if (tag === BatchedRoot) { + mode = BatchedMode | StrictMode; + } else { + mode = NoMode; + } if (enableProfilerTimer && isDevToolsPresent) { // Always collect profile timings when DevTools are present. @@ -18801,23 +21737,24 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode( - pendingProps, - mode | ConcurrentMode | StrictMode, - expirationTime, - key - ); + fiberTag = Mode; + mode |= ConcurrentMode | BatchedMode | StrictMode; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode( - pendingProps, - mode | StrictMode, - expirationTime, - key - ); + fiberTag = Mode; + mode |= StrictMode; + break; case REACT_PROFILER_TYPE: return createFiberFromProfiler(pendingProps, mode, expirationTime, key); case REACT_SUSPENSE_TYPE: return createFiberFromSuspense(pendingProps, mode, expirationTime, key); + case REACT_SUSPENSE_LIST_TYPE: + return createFiberFromSuspenseList( + pendingProps, + mode, + expirationTime, + key + ); default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -18841,20 +21778,9 @@ function createFiberFromTypeAndProps( fiberTag = LazyComponent; resolvedType = null; break getTag; - case REACT_EVENT_COMPONENT_TYPE: - if (enableEventAPI) { - return createFiberFromEventComponent( - type, - pendingProps, - mode, - expirationTime, - key - ); - } - break; - case REACT_EVENT_TARGET_TYPE: - if (enableEventAPI) { - return createFiberFromEventTarget( + case REACT_FUNDAMENTAL_TYPE: + if (enableFundamentalAPI) { + return createFiberFromFundamental( type, pendingProps, mode, @@ -18886,10 +21812,12 @@ function createFiberFromTypeAndProps( (function() { { throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (type == null ? type : typeof type) + - "." + - info + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (type == null ? type : typeof type) + + "." + + info + ) ); } })(); @@ -18934,35 +21862,17 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { return fiber; } -function createFiberFromEventComponent( - eventComponent, - pendingProps, - mode, - expirationTime, - key -) { - var fiber = createFiber(EventComponent, pendingProps, key, mode); - fiber.elementType = eventComponent; - fiber.type = eventComponent; - fiber.expirationTime = expirationTime; - return fiber; -} - -function createFiberFromEventTarget( - eventTarget, +function createFiberFromFundamental( + fundamentalComponent, pendingProps, mode, expirationTime, key ) { - var fiber = createFiber(EventTarget, pendingProps, key, mode); - fiber.elementType = eventTarget; - fiber.type = eventTarget; + var fiber = createFiber(FundamentalComponent, pendingProps, key, mode); + fiber.elementType = fundamentalComponent; + fiber.type = fundamentalComponent; fiber.expirationTime = expirationTime; - // Store latest props - fiber.stateNode = { - props: pendingProps - }; return fiber; } @@ -18988,29 +21898,28 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { return fiber; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - var fiber = createFiber(Mode, pendingProps, key, mode); +function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { + var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); - // TODO: The Mode fiber shouldn't have a type. It has a tag. - var type = - (mode & ConcurrentMode) === NoContext - ? REACT_STRICT_MODE_TYPE - : REACT_CONCURRENT_MODE_TYPE; - fiber.elementType = type; - fiber.type = type; + // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + fiber.type = REACT_SUSPENSE_TYPE; + fiber.elementType = REACT_SUSPENSE_TYPE; fiber.expirationTime = expirationTime; return fiber; } -function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { - var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); - - // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. - var type = REACT_SUSPENSE_TYPE; - fiber.elementType = type; - fiber.type = type; - +function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) { + var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode); + { + // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + fiber.type = REACT_SUSPENSE_LIST_TYPE; + } + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; fiber.expirationTime = expirationTime; return fiber; } @@ -19022,7 +21931,7 @@ function createFiberFromText(content, mode, expirationTime) { } function createFiberFromHostInstanceForDeletion() { - var fiber = createFiber(HostComponent, null, null, NoContext); + var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. fiber.elementType = "DELETED"; fiber.type = "DELETED"; @@ -19046,7 +21955,7 @@ function assignFiberPropertiesInDEV(target, source) { if (target === null) { // This Fiber's initial properties will always be overwritten. // We only use a Fiber to ensure the same hidden class so DEV isn't slow. - target = createFiber(IndeterminateComponent, null, null, NoContext); + target = createFiber(IndeterminateComponent, null, null, NoMode); } // This is intentionally written as a list of all properties. @@ -19069,7 +21978,7 @@ function assignFiberPropertiesInDEV(target, source) { target.memoizedProps = source.memoizedProps; target.updateQueue = source.updateQueue; target.memoizedState = source.memoizedState; - target.contextDependencies = source.contextDependencies; + target.dependencies = source.dependencies; target.mode = source.mode; target.effectTag = source.effectTag; target.nextEffect = source.nextEffect; @@ -19106,12 +22015,13 @@ function assignFiberPropertiesInDEV(target, source) { // The types are defined separately within this file to ensure they stay in sync. // (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.) -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pendingChildren = null; this.pingCache = null; - this.pendingCommitExpirationTime = NoWork; + this.finishedExpirationTime = NoWork; this.finishedWork = null; this.timeoutHandle = noTimeout; this.context = null; @@ -19131,12 +22041,12 @@ function FiberRootNode(containerInfo, hydrate) { } } -function createFiberRoot(containerInfo, isConcurrent, hydrate) { - var root = new FiberRootNode(containerInfo, hydrate); +function createFiberRoot(containerInfo, tag, hydrate) { + var root = new FiberRootNode(containerInfo, tag, hydrate); // Cyclic construction. This cheats the type system right now because // stateNode is any. - var uninitializedFiber = createHostRootFiber(isConcurrent); + var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -19182,7 +22092,13 @@ function getContextForSubtree(parentComponent) { return parentContext; } -function scheduleRootUpdate(current$$1, element, expirationTime, callback) { +function scheduleRootUpdate( + current$$1, + element, + expirationTime, + suspenseConfig, + callback +) { { if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; @@ -19197,7 +22113,7 @@ function scheduleRootUpdate(current$$1, element, expirationTime, callback) { } } - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property // being called "element". update.payload = { element: element }; @@ -19215,7 +22131,9 @@ function scheduleRootUpdate(current$$1, element, expirationTime, callback) { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(current$$1, update); scheduleWork(current$$1, expirationTime); @@ -19227,6 +22145,7 @@ function updateContainerAtExpirationTime( container, parentComponent, expirationTime, + suspenseConfig, callback ) { // TODO: If this is a nested container, this won't be the root. @@ -19251,7 +22170,13 @@ function updateContainerAtExpirationTime( container.pendingContext = context; } - return scheduleRootUpdate(current$$1, element, expirationTime, callback); + return scheduleRootUpdate( + current$$1, + element, + expirationTime, + suspenseConfig, + callback + ); } function findHostInstance(component) { @@ -19260,15 +22185,19 @@ function findHostInstance(component) { if (typeof component.render === "function") { (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } else { (function() { { throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } })(); @@ -19288,15 +22217,19 @@ function findHostInstanceWithWarning(component, methodName) { if (typeof component.render === "function") { (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } else { (function() { { throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } })(); @@ -19346,19 +22279,31 @@ function findHostInstanceWithWarning(component, methodName) { return findHostInstance(component); } -function createContainer(containerInfo, isConcurrent, hydrate) { - return createFiberRoot(containerInfo, isConcurrent, hydrate); +function createContainer(containerInfo, tag, hydrate) { + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current; var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, current$$1); + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(current$$1); + } + } + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); return updateContainerAtExpirationTime( element, container, parentComponent, expirationTime, + suspenseConfig, callback ); } @@ -19415,7 +22360,9 @@ var setSuspenseHandler = null; id--; } if (currentHook !== null) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } var newState = copyWithSet(currentHook.memoizedState, path, value); currentHook.memoizedState = newState; @@ -19434,7 +22381,9 @@ var setSuspenseHandler = null; // Support DevTools props for function components, forwardRef, memo, host components, etc. overrideProps = function(fiber, path, value) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); if (fiber.alternate) { fiber.alternate.pendingProps = fiber.pendingProps; @@ -19443,7 +22392,9 @@ var setSuspenseHandler = null; }; scheduleUpdate = function(fiber) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } scheduleWork(fiber, Sync); }; @@ -19482,7 +22433,11 @@ function injectIntoDevTools(devToolsConfig) { findHostInstancesForRefresh: findHostInstancesForRefresh, scheduleRefresh: scheduleRefresh, scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: function() { + return current; + } }) ); } @@ -19799,7 +22754,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps ) ) { - throw ReactError("Do not override existing functions."); + throw ReactError(Error("Do not override existing functions.")); } })(); // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, @@ -19829,13 +22784,13 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { return NativeMethodsMixin; }; -function _classCallCheck$1(instance, Constructor) { +function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _possibleConstructorReturn(self, call) { +function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError( "this hasn't been initialised - super() hasn't been called" @@ -19846,7 +22801,7 @@ function _possibleConstructorReturn(self, call) { : self; } -function _inherits(subClass, superClass) { +function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError( "Super expression must either be null or a function, not " + @@ -19868,7 +22823,7 @@ function _inherits(subClass, superClass) { } // Modules provided by RN: -var ReactNativeComponent = function(findNodeHandle, findHostInstance) { +var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { /** * Superclass that provides methods to access the underlying native component. * This can be useful when you want to focus a view or measure its dimensions. @@ -19881,12 +22836,12 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { * @abstract */ var ReactNativeComponent = (function(_React$Component) { - _inherits(ReactNativeComponent, _React$Component); + _inherits$1(ReactNativeComponent, _React$Component); function ReactNativeComponent() { - _classCallCheck$1(this, ReactNativeComponent); + _classCallCheck$2(this, ReactNativeComponent); - return _possibleConstructorReturn( + return _possibleConstructorReturn$1( this, _React$Component.apply(this, arguments) ); @@ -20156,16 +23111,16 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { return ReactNativeComponent; }; -var instanceCache = {}; +var instanceCache = new Map(); function getInstanceFromTag(tag) { - return instanceCache[tag] || null; + return instanceCache.get(tag) || null; } // Module provided by RN: -var emptyObject$1 = {}; +var emptyObject$2 = {}; { - Object.freeze(emptyObject$1); + Object.freeze(emptyObject$2); } var getInspectorDataForViewTag = void 0; @@ -20198,9 +23153,9 @@ var getInspectorDataForViewTag = void 0; var getHostProps = function(fiber) { var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$1; + return host.memoizedProps || emptyObject$2; } - return emptyObject$1; + return emptyObject$2; }; var getHostNode = function(fiber, findNodeHandle) { @@ -20246,7 +23201,7 @@ var getInspectorDataForViewTag = void 0; if (!closestInstance) { return { hierarchy: [], - props: emptyObject$1, + props: emptyObject$2, selection: null, source: null }; @@ -20269,6 +23224,9 @@ var getInspectorDataForViewTag = void 0; }; } +var _nativeFabricUIManage = nativeFabricUIManager; +var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand; + var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function findNodeHandle(componentOrHandle) { @@ -20325,14 +23283,15 @@ function findNodeHandle(componentOrHandle) { setBatchingImplementation( batchedUpdates$1, - interactiveUpdates$1, - flushInteractiveUpdates$1 + discreteUpdates$1, + flushDiscreteUpdates, + batchedEventUpdates$1 ); var roots = new Map(); var ReactFabric = { - NativeComponent: ReactNativeComponent(findNodeHandle, findHostInstance), + NativeComponent: ReactNativeComponent$1(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, @@ -20344,13 +23303,34 @@ var ReactFabric = { return; }, + dispatchCommand: function(handle, command, args) { + var invalid = + handle._nativeTag == null || handle._internalInstanceHandle == null; + + if (invalid) { + !!invalid + ? warningWithoutStack$1( + false, + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ) + : void 0; + return; + } + + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); 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, false, false); + root = createContainer(containerTag, LegacyRoot, false); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 5b5cc3c0015dbb..543906e39c31f7 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -14,10 +14,9 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -function ReactError(message) { - message = Error(message); - message.name = "Invariant Violation"; - return message; +function ReactError(error) { + error.name = "Invariant Violation"; + return error; } var eventPluginOrder = null, namesToPlugins = {}; @@ -28,16 +27,20 @@ function recomputePluginOrdering() { pluginIndex = eventPluginOrder.indexOf(pluginName); if (!(-1 < pluginIndex)) throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); if (!plugins[pluginIndex]) { if (!pluginModule.extractEvents) throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); plugins[pluginIndex] = pluginModule; pluginIndex = pluginModule.eventTypes; @@ -48,9 +51,11 @@ function recomputePluginOrdering() { eventName$jscomp$0 = eventName; if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ) ); eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -76,11 +81,13 @@ function recomputePluginOrdering() { : (JSCompiler_inline_result = !1); if (!JSCompiler_inline_result) throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } } @@ -89,9 +96,11 @@ function recomputePluginOrdering() { function publishRegistrationName(registrationName, pluginModule) { if (registrationNameModules[registrationName]) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); registrationNameModules[registrationName] = pluginModule; } @@ -140,7 +149,9 @@ function invokeGuardedCallbackAndCatchFirstError( caughtError = null; } else throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } @@ -158,7 +169,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; if (Array.isArray(dispatchListener)) - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null; @@ -171,7 +182,9 @@ function executeDirectDispatch(event) { function accumulateInto(current, next) { if (null == next) throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); if (null == current) return next; if (Array.isArray(current)) { @@ -208,7 +221,9 @@ var injection = { injectEventPluginOrder: function(injectedEventPluginOrder) { if (eventPluginOrder) throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); @@ -225,9 +240,11 @@ var injection = { ) { if (namesToPlugins[pluginName]) throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); namesToPlugins[pluginName] = pluginModule; isOrderingDirty = !0; @@ -269,11 +286,13 @@ function getListener(inst, registrationName) { if (inst) return null; if (listener && "function" !== typeof listener) throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); return listener; } @@ -437,7 +456,9 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { if (!(event instanceof this)) throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); event.destructor(); 10 > this.eventPool.length && this.eventPool.push(event); @@ -473,7 +494,8 @@ function timestampForTouch(touch) { } function getTouchIdentifier(_ref) { _ref = _ref.identifier; - if (null == _ref) throw ReactError("Touch object is missing identifier."); + if (null == _ref) + throw ReactError(Error("Touch object is missing identifier.")); return _ref; } function recordTouchStart(touch) { @@ -516,7 +538,7 @@ function recordTouchMove(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch move without a touch start.\nTouch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -534,7 +556,7 @@ function recordTouchEnd(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch end without a touch start.\nTouch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -588,7 +610,7 @@ var ResponderTouchHistoryStore = { function accumulate(current, next) { if (null == next) throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error("accumulate(...): Accumulated items must not be null or undefined.") ); return null == current ? next @@ -966,7 +988,9 @@ injection.injectEventPluginsByName({ directDispatchConfig = customDirectEventTypes[topLevelType]; if (!bubbleDispatchConfig && !directDispatchConfig) throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); topLevelType = SyntheticEvent.getPooled( bubbleDispatchConfig || directDispatchConfig, @@ -992,7 +1016,7 @@ getFiberCurrentPropsFromNode = function(inst) { getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { inst = inst.stateNode.canonical._nativeTag; - if (!inst) throw ReactError("All native instances should have a tag."); + if (!inst) throw ReactError(Error("All native instances should have a tag.")); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1009,6 +1033,8 @@ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher") || (ReactSharedInternals.ReactCurrentDispatcher = { current: null }); +ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig") || + (ReactSharedInternals.ReactCurrentBatchConfig = { suspense: null }); var hasSymbol = "function" === typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, @@ -1022,11 +1048,13 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, + REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; -hasSymbol && Symbol.for("react.event_component"); -hasSymbol && Symbol.for("react.event_target"); -hasSymbol && Symbol.for("react.event_target.touch_hit"); +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; @@ -1035,14 +1063,11 @@ function getIteratorFn(maybeIterable) { maybeIterable["@@iterator"]; return "function" === typeof maybeIterable ? maybeIterable : null; } -require("../shims/ReactFeatureFlags"); function getComponentName(type) { if (null == type) return null; if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -1053,6 +1078,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1087,14 +1114,14 @@ function isFiberMountedImpl(fiber) { } function assertIsMounted(fiber) { if (2 !== isFiberMountedImpl(fiber)) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; if (!alternate) { alternate = isFiberMountedImpl(fiber); if (3 === alternate) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return 1 === alternate ? null : fiber; } for (var a = fiber, b = alternate; ; ) { @@ -1115,7 +1142,7 @@ function findCurrentFiberUsingSlowPath(fiber) { if (parentB === b) return assertIsMounted(parentA), alternate; parentB = parentB.sibling; } - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } if (a.return !== b.return) (a = parentA), (b = parentB); else { @@ -1152,17 +1179,21 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (!didFindChild) throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } } if (a.alternate !== b) throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (3 !== a.tag) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return a.stateNode.current === a ? fiber : alternate; } function findCurrentHostFiber(parent) { @@ -1415,23 +1446,29 @@ var restoreTarget = null, function restoreStateOfTarget(target) { if (getInstanceFromNode(target)) throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } -function _batchedUpdatesImpl(fn, bookkeeping) { +require("../shims/ReactFeatureFlags"); +function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } -function _flushInteractiveUpdatesImpl() {} -var isBatching = !1; +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { - if (isBatching) return fn(bookkeeping); - isBatching = !0; + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - if (((isBatching = !1), null !== restoreTarget || null !== restoreQueue)) + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) if ( - (_flushInteractiveUpdatesImpl(), + (flushDiscreteUpdatesImpl(), restoreTarget && ((bookkeeping = restoreTarget), (fn = restoreQueue), @@ -1443,6 +1480,51 @@ function batchedUpdates(fn, bookkeeping) { restoreStateOfTarget(fn[bookkeeping]); } } +function _inherits(subClass, superClass) { + if ("function" !== typeof superClass && null !== superClass) + throw new TypeError( + "Super expression must either be null or a function, not " + + typeof superClass + ); + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: !1, + writable: !0, + configurable: !0 + } + }); + superClass && + (Object.setPrototypeOf + ? Object.setPrototypeOf(subClass, superClass) + : (subClass.__proto__ = superClass)); +} +(function(_React$Component) { + function ReactNativeComponent() { + if (!(this instanceof ReactNativeComponent)) + throw new TypeError("Cannot call a class as a function"); + var call = _React$Component.apply(this, arguments); + if (!this) + throw new ReferenceError( + "this hasn't been initialised - super() hasn't been called" + ); + return !call || ("object" !== typeof call && "function" !== typeof call) + ? this + : call; + } + _inherits(ReactNativeComponent, _React$Component); + ReactNativeComponent.prototype.blur = function() {}; + ReactNativeComponent.prototype.focus = function() {}; + ReactNativeComponent.prototype.measure = function() {}; + ReactNativeComponent.prototype.measureInWindow = function() {}; + ReactNativeComponent.prototype.measureLayout = function() {}; + ReactNativeComponent.prototype.setNativeProps = function() {}; + return ReactNativeComponent; +})(React.Component); +new Map(); +new Map(); +new Set(); +new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { batchedUpdates(function() { var events = nativeEvent.target; @@ -1465,7 +1547,9 @@ function dispatchEvent(target, topLevelType, nativeEvent) { forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); if (eventQueue) throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); if (hasRethrowError) throw ((events = rethrowError), @@ -1477,24 +1561,26 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } function shim$1() { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, +var _nativeFabricUIManage$1 = nativeFabricUIManager, + createNode = _nativeFabricUIManage$1.createNode, + cloneNode = _nativeFabricUIManage$1.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage$1.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, + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage$1.createChildSet, + appendChildNode = _nativeFabricUIManage$1.appendChild, + appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, + completeRoot = _nativeFabricUIManage$1.completeRoot, + registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, + fabricMeasure = _nativeFabricUIManage$1.measure, + fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1556,7 +1642,7 @@ function createTextInstance( ) { if (!hostContext.isInAParentText) throw ReactError( - "Text strings must be rendered within a component." + Error("Text strings must be rendered within a component.") ); hostContext = nextReactTag; nextReactTag += 2; @@ -1671,7 +1757,9 @@ function popTopLevelContextObject(fiber) { function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); @@ -1684,10 +1772,12 @@ function processChildContext(fiber, type, parentContext) { for (var contextKey in instance) if (!(contextKey in fiber)) throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); return Object.assign({}, parentContext, instance); } @@ -1709,7 +1799,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { var instance = workInProgress.stateNode; if (!instance) throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); didChange ? ((type = processChildContext(workInProgress, type, previousContext)), @@ -1720,38 +1812,11 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -var onCommitFiberRoot = null, - onCommitFiberUnmount = null; -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) {} - }; -} -function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - var rendererID = hook.inject(internals); - onCommitFiberRoot = catchErrors(function(root) { - hook.onCommitFiberRoot( - rendererID, - root, - void 0, - 64 === (root.current.effectTag & 64) - ); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) {} - return !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 = Scheduler.unstable_now, Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel, @@ -1761,10 +1826,11 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_LowPriority = Scheduler.unstable_LowPriority, Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, fakeCallbackNode = {}, - shouldYield = Scheduler.unstable_shouldYield, - immediateQueue = null, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, immediateQueueCallbackNode = null, - isFlushingImmediate = !1, + isFlushingSyncQueue = !1, initialTimeMs = Scheduler_now(), now = 1e4 > initialTimeMs @@ -1785,7 +1851,7 @@ function getCurrentPriorityLevel() { case Scheduler_IdlePriority: return 95; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function reactPriorityToSchedulerPriority(reactPriorityLevel) { @@ -1801,54 +1867,55 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case 95: return Scheduler_IdlePriority; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (99 === reactPriorityLevel) - return ( - null === immediateQueue - ? ((immediateQueue = [callback]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ))) - : immediateQueue.push(callback), - fakeCallbackNode - ); reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function flushImmediateQueue() { +function scheduleSyncCallback(callback) { + null === syncQueue + ? ((syncQueue = [callback]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(callback); + return fakeCallbackNode; +} +function flushSyncCallbackQueue() { null !== immediateQueueCallbackNode && Scheduler_cancelCallback(immediateQueueCallbackNode); - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && null !== immediateQueue) { - isFlushingImmediate = !0; +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; var i = 0; try { - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do callback = callback(!0); - while (null !== callback); - } - immediateQueue = null; + var queue = syncQueue; + runWithPriority$1(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; } catch (error) { - throw (null !== immediateQueue && - (immediateQueue = immediateQueue.slice(i + 1)), + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ), error); } finally { - isFlushingImmediate = !1; + isFlushingSyncQueue = !1; } } } @@ -1856,7 +1923,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (1073741823 === expirationTime) return 99; if (1 === expirationTime) return 95; currentTime = - 10 * (1073741822 - expirationTime) - 10 * (1073741822 - currentTime); + 10 * (1073741821 - expirationTime) - 10 * (1073741821 - currentTime); return 0 >= currentTime ? 99 : 250 >= currentTime @@ -1938,7 +2005,7 @@ var valueCursor = { current: null }, currentlyRenderingFiber = null, lastContextDependency = null, lastContextWithAllBitsObserved = null; -function resetContextDependences() { +function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } function pushProvider(providerFiber, nextValue) { @@ -1951,14 +2018,32 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); providerFiber.type._context._currentValue2 = currentValue; } +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + for (; null !== parent; ) { + var alternate = parent.alternate; + if (parent.childExpirationTime < renderExpirationTime) + (parent.childExpirationTime = renderExpirationTime), + null !== alternate && + alternate.childExpirationTime < renderExpirationTime && + (alternate.childExpirationTime = renderExpirationTime); + else if ( + null !== alternate && + alternate.childExpirationTime < renderExpirationTime + ) + alternate.childExpirationTime = renderExpirationTime; + else break; + parent = parent.return; + } +} function prepareToReadContext(workInProgress, renderExpirationTime) { currentlyRenderingFiber = workInProgress; lastContextWithAllBitsObserved = lastContextDependency = null; - var currentDependencies = workInProgress.contextDependencies; - null !== currentDependencies && - currentDependencies.expirationTime >= renderExpirationTime && - (didReceiveUpdate = !0); - workInProgress.contextDependencies = null; + workInProgress = workInProgress.dependencies; + null !== workInProgress && + null !== workInProgress.firstContext && + (workInProgress.expirationTime >= renderExpirationTime && + (didReceiveUpdate = !0), + (workInProgress.firstContext = null)); } function readContext(context, observedBits) { if ( @@ -1972,12 +2057,16 @@ function readContext(context, observedBits) { if (null === lastContextDependency) { if (null === currentlyRenderingFiber) throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); lastContextDependency = observedBits; - currentlyRenderingFiber.contextDependencies = { - first: observedBits, - expirationTime: 0 + currentlyRenderingFiber.dependencies = { + expirationTime: 0, + firstContext: observedBits, + listeners: null, + responders: null }; } else lastContextDependency = lastContextDependency.next = observedBits; } @@ -2010,9 +2099,10 @@ function cloneUpdateQueue(currentQueue) { lastCapturedEffect: null }; } -function createUpdate(expirationTime) { +function createUpdate(expirationTime, suspenseConfig) { return { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, @@ -2128,8 +2218,10 @@ function processUpdateQueue( ((newFirstUpdate = update), (newBaseState = resultState)), newExpirationTime < updateExpirationTime && (newExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), (resultState = getStateFromUpdate( workInProgress, queue, @@ -2205,15 +2297,18 @@ function commitUpdateEffects(effect, instance) { var context = instance; if ("function" !== typeof _callback3) throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - _callback3 + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + _callback3 + ) ); _callback3.call(context); } effect = effect.nextEffect; } } -var emptyRefsObject = new React.Component().refs; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + emptyRefsObject = new React.Component().refs; function applyDerivedStateFromProps( workInProgress, ctor, @@ -2240,36 +2335,42 @@ var classComponentUpdater = { }, enqueueSetState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 1; + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 2; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 2; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); } }; @@ -2398,15 +2499,19 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); inst = element.stateNode; } if (!inst) throw ReactError( - "Missing owner for string ref " + - returnFiber + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + returnFiber + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); var stringRef = "" + returnFiber; if ( @@ -2426,13 +2531,17 @@ function coerceRef(returnFiber, current$$1, element) { } if ("string" !== typeof returnFiber) throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); if (!element._owner) throw ReactError( - "Element ref was specified as a string (" + - returnFiber + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + returnFiber + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } return returnFiber; @@ -2440,11 +2549,13 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) throw ReactError( - "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === Object.prototype.toString.call(newChild) + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + ) ); } function ChildReconciler(shouldTrackSideEffects) { @@ -2847,11 +2958,13 @@ function ChildReconciler(shouldTrackSideEffects) { var iteratorFn = getIteratorFn(newChildrenIterable); if ("function" !== typeof iteratorFn) throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); newChildrenIterable = iteratorFn.call(newChildrenIterable); if (null == newChildrenIterable) - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); for ( var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, @@ -3086,8 +3199,10 @@ function ChildReconciler(shouldTrackSideEffects) { case 0: throw ((returnFiber = returnFiber.type), ReactError( - (returnFiber.displayName || returnFiber.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (returnFiber.displayName || returnFiber.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) )); } return deleteRemainingChildren(returnFiber, currentFirstChild); @@ -3102,7 +3217,9 @@ var reconcileChildFibers = ChildReconciler(!0), function requiredContext(c) { if (c === NO_CONTEXT) throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); return c; } @@ -3140,6 +3257,50 @@ function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } +var SubtreeSuspenseContextMask = 1, + InvisibleParentSuspenseContext = 1, + ForceSuspenseFallback = 2, + suspenseStackCursor = { current: 0 }; +function findFirstSuspended(row) { + for (var node = row; null !== node; ) { + if (13 === node.tag) { + if (null !== node.memoizedState) return node; + } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { + if (0 !== (node.effectTag & 64)) return node; + } else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; +} +var currentListenerHookIndex = 0; +function updateListenerHook(responder, props) { + var dependencies = null.dependencies; + null === dependencies && + (dependencies = null.dependencies = { + expirationTime: 0, + firstContext: null, + listeners: [], + responders: null + }); + var listeners = dependencies.listeners; + null === listeners && (dependencies.listeners = listeners = []); + listeners.length === currentListenerHookIndex + ? (listeners.push({ responder: responder, props: props }), + currentListenerHookIndex++) + : ((listeners = listeners[currentListenerHookIndex++]), + (listeners.responder = responder), + (listeners.props = props)); +} var NoEffect$1 = 0, UnmountSnapshot = 2, UnmountMutation = 4, @@ -3164,7 +3325,9 @@ var NoEffect$1 = 0, numberOfReRenders = 0; function throwInvalidHookError() { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } function areHookInputsEqual(nextDeps, prevDeps) { @@ -3214,7 +3377,9 @@ function renderWithHooks( sideEffectTag = 0; if (current) throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); return workInProgress; } @@ -3250,7 +3415,9 @@ function updateWorkInProgressHook() { (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) - throw ReactError("Rendered more hooks than during the previous render."); + throw ReactError( + Error("Rendered more hooks than during the previous render.") + ); currentHook = nextCurrentHook; var newHook = { memoizedState: currentHook.memoizedState, @@ -3275,7 +3442,9 @@ function updateReducer(reducer) { queue = hook.queue; if (null === queue) throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); queue.lastRenderedReducer = reducer; if (0 < numberOfReRenders) { @@ -3318,8 +3487,10 @@ function updateReducer(reducer) { (firstRenderPhaseUpdate = newState)), updateExpirationTime > remainingExpirationTime && (remainingExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ), (newState = _update.eagerReducer === reducer ? _update.eagerState @@ -3398,7 +3569,9 @@ function mountDebugValue() {} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); var alternate = fiber.alternate; if ( @@ -3409,6 +3582,7 @@ function dispatchAction(fiber, queue, action) { ((didScheduleRenderPhaseUpdate = !0), (fiber = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, @@ -3424,24 +3598,29 @@ function dispatchAction(fiber, queue, action) { queue.next = fiber; } else { - flushPassiveEffects(); - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, fiber); - var _update2 = { - expirationTime: currentTime, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }, - _last = queue.last; - if (null === _last) _update2.next = _update2; + var currentTime = requestCurrentTime(), + _suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); + _suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: _suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var _last = queue.last; + if (null === _last) _suspenseConfig.next = _suspenseConfig; else { var first = _last.next; - null !== first && (_update2.next = first); - _last.next = _update2; + null !== first && (_suspenseConfig.next = first); + _last.next = _suspenseConfig; } - queue.last = _update2; + queue.last = _suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3450,8 +3629,8 @@ function dispatchAction(fiber, queue, action) { try { var currentState = queue.lastRenderedState, _eagerState = alternate(currentState, action); - _update2.eagerReducer = alternate; - _update2.eagerState = _eagerState; + _suspenseConfig.eagerReducer = alternate; + _suspenseConfig.eagerState = _eagerState; if (is(_eagerState, currentState)) return; } catch (error) { } finally { @@ -3470,7 +3649,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3543,7 +3723,8 @@ var ContextOnlyDispatcher = { ); return [hook.memoizedState, initialState]; }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, HooksDispatcherOnUpdate = { readContext: readContext, @@ -3597,7 +3778,8 @@ var ContextOnlyDispatcher = { useState: function(initialState) { return updateReducer(basicStateReducer, initialState); }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, hydrationParentFiber = null, nextHydratableInstance = null, @@ -4138,6 +4320,7 @@ function pushHostRootContext(workInProgress) { pushTopLevelContextObject(workInProgress, root.context, !1); pushHostContainer(workInProgress, root.containerInfo); } +var SUSPENDED_MARKER = {}; function updateSuspenseComponent( current$$1, workInProgress, @@ -4145,100 +4328,271 @@ function updateSuspenseComponent( ) { var mode = workInProgress.mode, nextProps = workInProgress.pendingProps, - nextState = workInProgress.memoizedState; - if (0 === (workInProgress.effectTag & 64)) { - nextState = null; - var nextDidTimeout = !1; - } else - (nextState = { - fallbackExpirationTime: - null !== nextState ? nextState.fallbackExpirationTime : 0 - }), + suspenseContext = suspenseStackCursor.current, + nextState = null, + nextDidTimeout = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || + (JSCompiler_temp = + 0 !== (suspenseContext & ForceSuspenseFallback) && + (null === current$$1 || null !== current$$1.memoizedState)); + JSCompiler_temp + ? ((nextState = SUSPENDED_MARKER), (nextDidTimeout = !0), - (workInProgress.effectTag &= -65); + (workInProgress.effectTag &= -65)) + : (null !== current$$1 && null === current$$1.memoizedState) || + void 0 === nextProps.fallback || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= InvisibleParentSuspenseContext); + suspenseContext &= SubtreeSuspenseContextMask; + push(suspenseStackCursor, suspenseContext, workInProgress); if (null === current$$1) if (nextDidTimeout) { - var nextFallbackChildren = nextProps.fallback; + nextProps = nextProps.fallback; current$$1 = createFiberFromFragment(null, mode, 0, null); - 0 === (workInProgress.mode & 1) && - (current$$1.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child); - mode = createFiberFromFragment( - nextFallbackChildren, + current$$1.return = workInProgress; + if (0 === (workInProgress.mode & 2)) + for ( + nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + current$$1.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = current$$1), + (nextDidTimeout = nextDidTimeout.sibling); + renderExpirationTime = createFiberFromFragment( + nextProps, mode, renderExpirationTime, null ); - current$$1.sibling = mode; - renderExpirationTime = current$$1; - renderExpirationTime.return = mode.return = workInProgress; + renderExpirationTime.return = workInProgress; + current$$1.sibling = renderExpirationTime; + mode = current$$1; } else - renderExpirationTime = mode = mountChildFibers( + mode = renderExpirationTime = mountChildFibers( workInProgress, null, nextProps.children, renderExpirationTime ); - else - null !== current$$1.memoizedState - ? ((mode = current$$1.child), - (nextFallbackChildren = mode.sibling), - nextDidTimeout - ? ((renderExpirationTime = nextProps.fallback), - (nextProps = createWorkInProgress(mode, mode.pendingProps, 0)), - 0 === (workInProgress.mode & 1) && - ((nextDidTimeout = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child), - nextDidTimeout !== mode.child && - (nextProps.child = nextDidTimeout)), - (mode = nextProps.sibling = createWorkInProgress( - nextFallbackChildren, - renderExpirationTime, - nextFallbackChildren.expirationTime - )), - (renderExpirationTime = nextProps), - (nextProps.childExpirationTime = 0), - (renderExpirationTime.return = mode.return = workInProgress)) - : (renderExpirationTime = mode = reconcileChildFibers( - workInProgress, - mode.child, - nextProps.children, - renderExpirationTime - ))) - : ((nextFallbackChildren = current$$1.child), - nextDidTimeout - ? ((nextDidTimeout = nextProps.fallback), - (nextProps = createFiberFromFragment(null, mode, 0, null)), - (nextProps.child = nextFallbackChildren), - 0 === (workInProgress.mode & 1) && - (nextProps.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child), - (mode = nextProps.sibling = createFiberFromFragment( - nextDidTimeout, - mode, - renderExpirationTime, - null - )), - (mode.effectTag |= 2), - (renderExpirationTime = nextProps), - (nextProps.childExpirationTime = 0), - (renderExpirationTime.return = mode.return = workInProgress)) - : (mode = renderExpirationTime = reconcileChildFibers( - workInProgress, - nextFallbackChildren, - nextProps.children, - renderExpirationTime - ))), - (workInProgress.stateNode = current$$1.stateNode); + else { + if (null !== current$$1.memoizedState) + if ( + ((suspenseContext = current$$1.child), + (mode = suspenseContext.sibling), + nextDidTimeout) + ) { + nextProps = nextProps.fallback; + renderExpirationTime = createWorkInProgress( + suspenseContext, + suspenseContext.pendingProps, + 0 + ); + renderExpirationTime.return = workInProgress; + if ( + 0 === (workInProgress.mode & 2) && + ((nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child), + nextDidTimeout !== suspenseContext.child) + ) + for ( + renderExpirationTime.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = renderExpirationTime), + (nextDidTimeout = nextDidTimeout.sibling); + nextProps = createWorkInProgress(mode, nextProps, mode.expirationTime); + nextProps.return = workInProgress; + renderExpirationTime.sibling = nextProps; + mode = renderExpirationTime; + renderExpirationTime.childExpirationTime = 0; + renderExpirationTime = nextProps; + } else + mode = renderExpirationTime = reconcileChildFibers( + workInProgress, + suspenseContext.child, + nextProps.children, + renderExpirationTime + ); + else if (((suspenseContext = current$$1.child), nextDidTimeout)) { + nextDidTimeout = nextProps.fallback; + nextProps = createFiberFromFragment(null, mode, 0, null); + nextProps.return = workInProgress; + nextProps.child = suspenseContext; + null !== suspenseContext && (suspenseContext.return = nextProps); + if (0 === (workInProgress.mode & 2)) + for ( + suspenseContext = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + nextProps.child = suspenseContext; + null !== suspenseContext; + + ) + (suspenseContext.return = nextProps), + (suspenseContext = suspenseContext.sibling); + renderExpirationTime = createFiberFromFragment( + nextDidTimeout, + mode, + renderExpirationTime, + null + ); + renderExpirationTime.return = workInProgress; + nextProps.sibling = renderExpirationTime; + renderExpirationTime.effectTag |= 2; + mode = nextProps; + nextProps.childExpirationTime = 0; + } else + renderExpirationTime = mode = reconcileChildFibers( + workInProgress, + suspenseContext, + nextProps.children, + renderExpirationTime + ); + workInProgress.stateNode = current$$1.stateNode; + } workInProgress.memoizedState = nextState; - workInProgress.child = renderExpirationTime; - return mode; + workInProgress.child = mode; + return renderExpirationTime; +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailExpiration = 0), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren( + current$$1, + workInProgress, + nextProps.children, + renderExpirationTime + ); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & ForceSuspenseFallback)) + (nextProps = + (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), + (workInProgress.effectTag |= 64); + else { + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) { + if (null !== current$$1.memoizedState) { + current$$1.expirationTime < renderExpirationTime && + (current$$1.expirationTime = renderExpirationTime); + var alternate = current$$1.alternate; + null !== alternate && + alternate.expirationTime < renderExpirationTime && + (alternate.expirationTime = renderExpirationTime); + scheduleWorkOnParentPath(current$$1.return, renderExpirationTime); + } + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) + break a; + current$$1 = current$$1.return; + } + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + nextProps &= SubtreeSuspenseContextMask; + } + push(suspenseStackCursor, nextProps, workInProgress); + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderExpirationTime = workInProgress.child; + for (revealOrder = null; null !== renderExpirationTime; ) + (nextProps = renderExpirationTime.alternate), + null !== nextProps && + null === findFirstSuspended(nextProps) && + (revealOrder = renderExpirationTime), + (renderExpirationTime = renderExpirationTime.sibling); + renderExpirationTime = revealOrder; + null === renderExpirationTime + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderExpirationTime.sibling), + (renderExpirationTime.sibling = null)); + initSuspenseListRenderState( + workInProgress, + !1, + revealOrder, + renderExpirationTime, + tailMode + ); + break; + case "backwards": + renderExpirationTime = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + nextProps = revealOrder.alternate; + if (null !== nextProps && null === findFirstSuspended(nextProps)) { + workInProgress.child = revealOrder; + break; + } + nextProps = revealOrder.sibling; + revealOrder.sibling = renderExpirationTime; + renderExpirationTime = revealOrder; + revealOrder = nextProps; + } + initSuspenseListRenderState( + workInProgress, + !0, + renderExpirationTime, + null, + tailMode + ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; + } + return workInProgress.child; } function bailoutOnAlreadyFinishedWork( current$$1, @@ -4246,10 +4600,10 @@ function bailoutOnAlreadyFinishedWork( renderExpirationTime ) { null !== current$$1 && - (workInProgress.contextDependencies = current$$1.contextDependencies); + (workInProgress.dependencies = current$$1.dependencies); if (workInProgress.childExpirationTime < renderExpirationTime) return null; if (null !== current$$1 && workInProgress.child !== current$$1.child) - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); if (null !== workInProgress.child) { current$$1 = workInProgress.child; renderExpirationTime = createWorkInProgress( @@ -4460,6 +4814,74 @@ updateHostText$1 = function(current, workInProgress, oldText, newText) { )), (workInProgress.effectTag |= 4)); }; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var _lastTailNode = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === _lastTailNode + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (_lastTailNode.sibling = null); + } +} +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + workInProgress.effectTag = (effectTag & -2049) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null + ); + case 18: + return null; + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} function createCapturedValue(value, source) { return { value: value, @@ -4467,24 +4889,18 @@ function createCapturedValue(value, source) { stack: getStackByFiberInDevAndProd(source) }; } +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") + ); function logCapturedError(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - if (error instanceof Error) { - capturedError = error.message; - var name = error.name; - try { - error.message = - (capturedError ? name + ": " + capturedError : name) + - "\n\nThis error is located at:" + - componentStack; - } catch (e) {} - } else - error = - "string" === typeof error - ? Error(error + "\n\nThis error is located at:" + componentStack) - : Error("Unspecified error at:" + componentStack); - ReactNativePrivateInterface.ExceptionsManager.handleException(error, !1); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ) && console.error(capturedError.error); } var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; function logError(boundary, errorInfo) { @@ -4555,7 +4971,12 @@ function commitWork(current$$1, finishedWork) { case 12: return; case 13: - commitSuspenseComponent(finishedWork); + null !== finishedWork.memoizedState && + (globalMostRecentFallbackTime = now()); + attachSuspenseRetryListeners(finishedWork); + return; + case 19: + attachSuspenseRetryListeners(finishedWork); return; } switch (finishedWork.tag) { @@ -4563,29 +4984,26 @@ function commitWork(current$$1, finishedWork) { case 5: case 6: case 20: - case 19: break; case 3: case 4: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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 commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; - null !== newState && - 0 === newState.fallbackExpirationTime && - (newState.fallbackExpirationTime = requestCurrentTime() - 500); - newState = finishedWork.updateQueue; - if (null !== newState) { +function attachSuspenseRetryListeners(finishedWork) { + var thenables = finishedWork.updateQueue; + if (null !== thenables) { finishedWork.updateQueue = null; var retryCache = finishedWork.stateNode; null === retryCache && (retryCache = finishedWork.stateNode = new PossiblyWeakSet$1()); - newState.forEach(function(thenable) { + thenables.forEach(function(thenable) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); retryCache.has(thenable) || (retryCache.add(thenable), thenable.then(retry, retry)); @@ -4594,7 +5012,7 @@ function commitSuspenseComponent(finishedWork) { } var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; expirationTime.payload = { element: null }; var error = errorInfo.value; @@ -4605,7 +5023,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { @@ -4631,64 +5049,29 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { }); return expirationTime; } -function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null; - case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -2049) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: - return ( - (effectTag = workInProgress.effectTag), - effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null - ); - case 18: - return null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 19: - case 20: - return null; - default: - return null; - } -} var ceil = Math.ceil, ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - LegacyUnbatchedPhase = 2, - RenderPhase = 4, - CommitPhase = 5, + NoContext = 0, + LegacyUnbatchedContext = 8, + RenderContext = 16, + CommitContext = 32, RootIncomplete = 0, RootErrored = 1, RootSuspended = 2, - RootCompleted = 3, - workPhase = 0, + RootSuspendedWithDelay = 3, + RootCompleted = 4, + executionContext = NoContext, workInProgressRoot = null, workInProgress = null, renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, - workInProgressRootMostRecentEventTime = 1073741823, + workInProgressRootLatestProcessedExpirationTime = 1073741823, + workInProgressRootLatestSuspenseTimeout = 1073741823, + workInProgressRootCanSuspendUsingConfig = null, + workInProgressRootHasPendingPing = !1, + globalMostRecentFallbackTime = 0, + FALLBACK_THROTTLE_MS = 500, nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, @@ -4700,34 +5083,49 @@ var ceil = Math.ceil, rootWithNestedUpdates = null, currentEventTime = 0; function requestCurrentTime() { - return workPhase === RenderPhase || workPhase === CommitPhase - ? 1073741822 - ((now() / 10) | 0) + return (executionContext & (RenderContext | CommitContext)) !== NoContext + ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime ? currentEventTime - : (currentEventTime = 1073741822 - ((now() / 10) | 0)); -} -function computeExpirationForFiber(currentTime, fiber) { - if (0 === (fiber.mode & 1)) return 1073741823; - if (workPhase === RenderPhase) return renderExpirationTime; - switch (getCurrentPriorityLevel()) { - case 99: - currentTime = 1073741823; - break; - case 98: - currentTime = - 1073741822 - 10 * ((((1073741822 - currentTime + 15) / 10) | 0) + 1); - break; - case 97: - case 96: - currentTime = - 1073741822 - 25 * ((((1073741822 - currentTime + 500) / 25) | 0) + 1); - break; - case 95: - currentTime = 1; - break; - default: - throw ReactError("Expected a valid priority level"); - } + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); +} +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + fiber = fiber.mode; + if (0 === (fiber & 2)) return 1073741823; + var priorityLevel = getCurrentPriorityLevel(); + if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; + if ((executionContext & RenderContext) !== NoContext) + return renderExpirationTime; + if (null !== suspenseConfig) + currentTime = + 1073741821 - + 25 * + ((((1073741821 - + currentTime + + (suspenseConfig.timeoutMs | 0 || 5e3) / 10) / + 25) | + 0) + + 1); + else + switch (priorityLevel) { + case 99: + currentTime = 1073741823; + break; + case 98: + currentTime = + 1073741821 - 10 * ((((1073741821 - currentTime + 15) / 10) | 0) + 1); + break; + case 97: + case 96: + currentTime = + 1073741821 - 25 * ((((1073741821 - currentTime + 500) / 25) | 0) + 1); + break; + case 95: + currentTime = 1; + break; + default: + throw ReactError(Error("Expected a valid priority level")); + } null !== workInProgressRoot && currentTime === renderExpirationTime && --currentTime; @@ -4738,33 +5136,37 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) )); fiber = markUpdateTimeFromFiberToRoot(fiber, expirationTime); - if (null !== fiber) - if (((fiber.pingTime = 0), 1073741823 === expirationTime)) - if (workPhase === LegacyUnbatchedPhase) + if (null !== fiber) { + fiber.pingTime = 0; + var priorityLevel = getCurrentPriorityLevel(); + if (1073741823 === expirationTime) + if ( + (executionContext & LegacyUnbatchedContext) !== NoContext && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) for ( - expirationTime = renderRoot(fiber, 1073741823, !0); - null !== expirationTime; + var callback = renderRoot(fiber, 1073741823, !0); + null !== callback; ) - expirationTime = expirationTime(!0); + callback = callback(!0); else scheduleCallbackForRoot(fiber, 99, 1073741823), - 0 === workPhase && flushImmediateQueue(); - else { - var priorityLevel = getCurrentPriorityLevel(); - if (98 === priorityLevel) - if (null === rootsWithPendingDiscreteUpdates) - rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]]); - else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(fiber); - (void 0 === lastDiscreteTime || lastDiscreteTime > expirationTime) && - rootsWithPendingDiscreteUpdates.set(fiber, expirationTime); - } - scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); - } + executionContext === NoContext && flushSyncCallbackQueue(); + else scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); + (executionContext & 4) === NoContext || + (98 !== priorityLevel && 99 !== priorityLevel) || + (null === rootsWithPendingDiscreteUpdates + ? (rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]])) + : ((priorityLevel = rootsWithPendingDiscreteUpdates.get(fiber)), + (void 0 === priorityLevel || priorityLevel > expirationTime) && + rootsWithPendingDiscreteUpdates.set(fiber, expirationTime))); + } } function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { fiber.expirationTime < expirationTime && @@ -4805,21 +5207,28 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode); root.callbackExpirationTime = expirationTime; - existingCallbackNode = null; - 1073741823 !== expirationTime && - 1 !== expirationTime && - ((existingCallbackNode = 10 * (1073741822 - expirationTime) - now()), - 5e3 < existingCallbackNode && (existingCallbackNode = 5e3), - (existingCallbackNode = { timeout: existingCallbackNode })); - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - existingCallbackNode - ); + 1073741823 === expirationTime + ? (root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + )) + : ((existingCallbackNode = null), + 1 !== expirationTime && + (existingCallbackNode = { + timeout: 10 * (1073741821 - expirationTime) - now() + }), + (root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + existingCallbackNode + ))); } } function runRootCallback(root, callback, isSync) { @@ -4843,9 +5252,7 @@ function resolveLocksOnRoot(root, expirationTime) { return null !== firstBatch && firstBatch._defer && firstBatch._expirationTime >= expirationTime - ? ((root.finishedWork = root.current.alternate), - (root.pendingCommitExpirationTime = expirationTime), - scheduleCallback(97, function() { + ? (scheduleCallback(97, function() { firstBatch._onComplete(); return null; }), @@ -4857,13 +5264,14 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback(99, renderRoot.bind(null, root, expirationTime)); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = 0; + root.finishedWork = null; + root.finishedExpirationTime = 0; var timeoutHandle = root.timeoutHandle; -1 !== timeoutHandle && ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); @@ -4887,6 +5295,12 @@ function prepareFreshStack(root, expirationTime) { case 4: popHostContainer(interruptedWork); break; + case 13: + pop(suspenseStackCursor, interruptedWork); + break; + case 19: + pop(suspenseStackCursor, interruptedWork); + break; case 10: popProvider(interruptedWork); } @@ -4896,24 +5310,33 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = 1073741823; + workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = !1; } function renderRoot(root$jscomp$0, expirationTime, isSync) { - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); if (root$jscomp$0.firstPendingTime < expirationTime) return null; - if (root$jscomp$0.pendingCommitExpirationTime === expirationTime) - return ( - (root$jscomp$0.pendingCommitExpirationTime = 0), - commitRoot.bind(null, root$jscomp$0, expirationTime) - ); + if (isSync && root$jscomp$0.finishedExpirationTime === expirationTime) + return commitRoot.bind(null, root$jscomp$0); flushPassiveEffects(); - (root$jscomp$0 === workInProgressRoot && - expirationTime === renderExpirationTime) || + if ( + root$jscomp$0 !== workInProgressRoot || + expirationTime !== renderExpirationTime + ) prepareFreshStack(root$jscomp$0, expirationTime); + else if (workInProgressRootExitStatus === RootSuspendedWithDelay) + if (workInProgressRootHasPendingPing) + prepareFreshStack(root$jscomp$0, expirationTime); + else { + var lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + } if (null !== workInProgress) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + lastPendingTime = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; null === prevDispatcher && (prevDispatcher = ContextOnlyDispatcher); ReactCurrentDispatcher.current = ContextOnlyDispatcher; @@ -4922,8 +5345,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) return ( - (workPhase = prevWorkPhase), - resetContextDependences(), + (executionContext = lastPendingTime), + resetContextDependencies(), (ReactCurrentDispatcher.current = prevDispatcher), renderRoot.bind(null, root$jscomp$0, currentTime) ); @@ -4935,16 +5358,16 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); else - for (; null !== workInProgress && !shouldYield(); ) + for (; null !== workInProgress && !Scheduler_shouldYield(); ) workInProgress = performUnitOfWork(workInProgress); break; } catch (thrownValue) { - resetContextDependences(); + resetContextDependencies(); resetHooks(); currentTime = workInProgress; if (null === currentTime || null === currentTime.return) throw (prepareFreshStack(root$jscomp$0, expirationTime), - (workPhase = prevWorkPhase), + (executionContext = lastPendingTime), thrownValue); a: { var root = root$jscomp$0, @@ -4959,29 +5382,41 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; + var thenable = value, + hasInvisibleParentBoundary = + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext); value = returnFiber; do { - if ( - 13 === value.tag && - (void 0 === value.memoizedProps.fallback - ? 0 - : null === value.memoizedState) - ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === value.tag)) + null !== value.memoizedState + ? (JSCompiler_temp = !1) + : ((JSCompiler_temp = value.memoizedProps), + (JSCompiler_temp = + void 0 === JSCompiler_temp.fallback + ? !1 + : !0 !== JSCompiler_temp.unstable_avoidThisFallback + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0)); + if (JSCompiler_temp) { returnFiber = value.updateQueue; null === returnFiber ? ((returnFiber = new Set()), returnFiber.add(thenable), (value.updateQueue = returnFiber)) : returnFiber.add(thenable); - if (0 === (value.mode & 1)) { + if (0 === (value.mode & 2)) { value.effectTag |= 64; sourceFiber.effectTag &= -1957; 1 === sourceFiber.tag && (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((renderExpirationTime$jscomp$0 = createUpdate( - 1073741823 + 1073741823, + null )), (renderExpirationTime$jscomp$0.tag = 2), enqueueUpdate( @@ -4993,15 +5428,15 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { } sourceFiber = root; root = renderExpirationTime$jscomp$0; - var pingCache = sourceFiber.pingCache; - null === pingCache - ? ((pingCache = sourceFiber.pingCache = new PossiblyWeakMap()), + hasInvisibleParentBoundary = sourceFiber.pingCache; + null === hasInvisibleParentBoundary + ? ((hasInvisibleParentBoundary = sourceFiber.pingCache = new PossiblyWeakMap()), (returnFiber = new Set()), - pingCache.set(thenable, returnFiber)) - : ((returnFiber = pingCache.get(thenable)), + hasInvisibleParentBoundary.set(thenable, returnFiber)) + : ((returnFiber = hasInvisibleParentBoundary.get(thenable)), void 0 === returnFiber && ((returnFiber = new Set()), - pingCache.set(thenable, returnFiber))); + hasInvisibleParentBoundary.set(thenable, returnFiber))); returnFiber.has(root) || (returnFiber.add(root), (sourceFiber = pingSuspendedRoot.bind( @@ -5023,11 +5458,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { getStackByFiberInDevAndProd(sourceFiber) ); } - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootErrored; + workInProgressRootExitStatus !== RootCompleted && + (workInProgressRootExitStatus = RootErrored); value = createCapturedValue(value, sourceFiber); sourceFiber = returnFiber; do { @@ -5079,76 +5511,144 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = completeUnitOfWork(currentTime); } while (1); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = lastPendingTime; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (null !== workInProgress) return renderRoot.bind(null, root$jscomp$0, expirationTime); } + root$jscomp$0.finishedWork = root$jscomp$0.current.alternate; + root$jscomp$0.finishedExpirationTime = expirationTime; if (resolveLocksOnRoot(root$jscomp$0, expirationTime)) return null; workInProgressRoot = null; switch (workInProgressRootExitStatus) { case RootIncomplete: - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); case RootErrored: return ( - (prevWorkPhase = root$jscomp$0.lastPendingTime), - root$jscomp$0.lastPendingTime < expirationTime - ? renderRoot.bind(null, root$jscomp$0, prevWorkPhase) + (lastPendingTime = root$jscomp$0.lastPendingTime), + lastPendingTime < expirationTime + ? renderRoot.bind(null, root$jscomp$0, lastPendingTime) : isSync - ? commitRoot.bind(null, root$jscomp$0, expirationTime) + ? commitRoot.bind(null, root$jscomp$0) : (prepareFreshStack(root$jscomp$0, expirationTime), - scheduleCallback( - 99, + scheduleSyncCallback( renderRoot.bind(null, root$jscomp$0, expirationTime) ), null) ); case RootSuspended: + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + !isSync && + ((isSync = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < isSync) + ) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); + lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + isSync + ); + return null; + } + return commitRoot.bind(null, root$jscomp$0); + case RootSuspendedWithDelay: if (!isSync) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); isSync = root$jscomp$0.lastPendingTime; - if (root$jscomp$0.lastPendingTime < expirationTime) + if (isSync < expirationTime) return renderRoot.bind(null, root$jscomp$0, isSync); - if ( - 1073741823 !== workInProgressRootMostRecentEventTime && - ((prevWorkPhase = - 10 * (1073741822 - workInProgressRootMostRecentEventTime) - 5e3), - (isSync = now()), - (prevWorkPhase = isSync - prevWorkPhase), - (prevWorkPhase = - (120 > prevWorkPhase - ? 120 - : 480 > prevWorkPhase - ? 480 - : 1080 > prevWorkPhase - ? 1080 - : 1920 > prevWorkPhase - ? 1920 - : 3e3 > prevWorkPhase - ? 3e3 - : 4320 > prevWorkPhase - ? 4320 - : 1960 * ceil(prevWorkPhase / 1960)) - prevWorkPhase), - (isSync = 10 * (1073741822 - expirationTime) - isSync), - isSync < prevWorkPhase && (prevWorkPhase = isSync), - (isSync = prevWorkPhase), - 10 < isSync) - ) + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (isSync = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (isSync = 0) + : ((isSync = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (lastPendingTime = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - lastPendingTime), + (isSync = lastPendingTime - isSync), + 0 > isSync && (isSync = 0), + (isSync = + (120 > isSync + ? 120 + : 480 > isSync + ? 480 + : 1080 > isSync + ? 1080 + : 1920 > isSync + ? 1920 + : 3e3 > isSync + ? 3e3 + : 4320 > isSync + ? 4320 + : 1960 * ceil(isSync / 1960)) - isSync), + expirationTime < isSync && (isSync = expirationTime)); + if (10 < isSync) return ( (root$jscomp$0.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root$jscomp$0, expirationTime), + commitRoot.bind(null, root$jscomp$0), isSync )), null ); } - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return commitRoot.bind(null, root$jscomp$0); case RootCompleted: - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return !isSync && + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig && + ((lastPendingTime = workInProgressRootLatestProcessedExpirationTime), + (prevDispatcher = workInProgressRootCanSuspendUsingConfig), + (expirationTime = prevDispatcher.busyMinDurationMs | 0), + 0 >= expirationTime + ? (expirationTime = 0) + : ((isSync = prevDispatcher.busyDelayMs | 0), + (lastPendingTime = + now() - + (10 * (1073741821 - lastPendingTime) - + (prevDispatcher.timeoutMs | 0 || 5e3))), + (expirationTime = + lastPendingTime <= isSync + ? 0 + : isSync + expirationTime - lastPendingTime)), + 10 < expirationTime) + ? ((root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + expirationTime + )), + null) + : commitRoot.bind(null, root$jscomp$0); default: - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } } +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 1 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 1 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} function performUnitOfWork(unitOfWork) { var next = beginWork$$1( unitOfWork.alternate, @@ -5185,10 +5685,11 @@ function completeUnitOfWork(unitOfWork) { case 3: popHostContainer(current$$1); popTopLevelContextObject(current$$1); - newProps = current$$1.stateNode; - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)); + renderExpirationTime$jscomp$0 = current$$1.stateNode; + renderExpirationTime$jscomp$0.pendingContext && + ((renderExpirationTime$jscomp$0.context = + renderExpirationTime$jscomp$0.pendingContext), + (renderExpirationTime$jscomp$0.pendingContext = null)); if (null === current || null === current.child) current$$1.effectTag &= -3; updateHostContainer(current$$1); @@ -5212,8 +5713,8 @@ function completeUnitOfWork(unitOfWork) { requiredContext(contextStackCursor$1.current); current = newProps; var rootContainerInstance = renderExpirationTime$jscomp$0; - newProps = current$$1; - renderExpirationTime$jscomp$0 = nextReactTag; + renderExpirationTime$jscomp$0 = current$$1; + newProps = nextReactTag; nextReactTag += 2; type = getViewConfigForType(type); var updatePayload = diffProperties( @@ -5223,17 +5724,17 @@ function completeUnitOfWork(unitOfWork) { type.validAttributes ); rootContainerInstance = createNode( - renderExpirationTime$jscomp$0, + newProps, type.uiViewClassName, rootContainerInstance, updatePayload, - newProps + renderExpirationTime$jscomp$0 ); current = new ReactFabricHostComponent( - renderExpirationTime$jscomp$0, + newProps, type, current, - newProps + renderExpirationTime$jscomp$0 ); current = { node: rootContainerInstance, canonical: current }; appendAllChildren(current, current$$1, !1, !1); @@ -5241,7 +5742,9 @@ function completeUnitOfWork(unitOfWork) { null !== current$$1.ref && (current$$1.effectTag |= 128); } else if (null === current$$1.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -5255,7 +5758,9 @@ function completeUnitOfWork(unitOfWork) { else { if ("string" !== typeof newProps && null === current$$1.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); current = requiredContext(rootInstanceStackCursor.current); renderExpirationTime$jscomp$0 = requiredContext( @@ -5272,36 +5777,47 @@ function completeUnitOfWork(unitOfWork) { case 11: break; case 13: + pop(suspenseStackCursor, current$$1); newProps = current$$1.memoizedState; if (0 !== (current$$1.effectTag & 64)) { current$$1.expirationTime = renderExpirationTime$jscomp$0; break a; } - newProps = null !== newProps; - renderExpirationTime$jscomp$0 = !1; + renderExpirationTime$jscomp$0 = null !== newProps; + newProps = !1; null !== current && ((type = current.memoizedState), - (renderExpirationTime$jscomp$0 = null !== type), - newProps || + (newProps = null !== type), + renderExpirationTime$jscomp$0 || null === type || - ((type = type.fallbackExpirationTime), - type < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = type), - (current = current.child.sibling), - null !== current && - ((type = current$$1.firstEffect), - null !== type - ? ((current$$1.firstEffect = current), - (current.nextEffect = type)) - : ((current$$1.firstEffect = current$$1.lastEffect = current), - (current.nextEffect = null)), - (current.effectTag = 8)))); - newProps && - !renderExpirationTime$jscomp$0 && - 0 !== (current$$1.mode & 1) && - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - newProps && (current$$1.effectTag |= 4); + ((type = current.child.sibling), + null !== type && + ((rootContainerInstance = current$$1.firstEffect), + null !== rootContainerInstance + ? ((current$$1.firstEffect = type), + (type.nextEffect = rootContainerInstance)) + : ((current$$1.firstEffect = current$$1.lastEffect = type), + (type.nextEffect = null)), + (type.effectTag = 8)))); + if ( + renderExpirationTime$jscomp$0 && + !newProps && + 0 !== (current$$1.mode & 2) + ) + if ( + (null === current && + !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + renderExpirationTime$jscomp$0 && (current$$1.effectTag |= 4); break; case 7: break; @@ -5326,33 +5842,167 @@ function completeUnitOfWork(unitOfWork) { case 18: break; case 19: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (null === newProps) break; + type = 0 !== (current$$1.effectTag & 64); + rootContainerInstance = newProps.rendering; + if (null === rootContainerInstance) + if (type) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = current$$1.child; null !== current; ) { + rootContainerInstance = findFirstSuspended(current); + if (null !== rootContainerInstance) { + current$$1.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = rootContainerInstance.updateQueue; + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)); + current$$1.firstEffect = current$$1.lastEffect = null; + current = renderExpirationTime$jscomp$0; + for ( + renderExpirationTime$jscomp$0 = current$$1.child; + null !== renderExpirationTime$jscomp$0; + + ) + (newProps = renderExpirationTime$jscomp$0), + (type = current), + (newProps.effectTag &= 2), + (newProps.nextEffect = null), + (newProps.firstEffect = null), + (newProps.lastEffect = null), + (rootContainerInstance = newProps.alternate), + null === rootContainerInstance + ? ((newProps.childExpirationTime = 0), + (newProps.expirationTime = type), + (newProps.child = null), + (newProps.memoizedProps = null), + (newProps.memoizedState = null), + (newProps.updateQueue = null), + (newProps.dependencies = null)) + : ((newProps.childExpirationTime = + rootContainerInstance.childExpirationTime), + (newProps.expirationTime = + rootContainerInstance.expirationTime), + (newProps.child = rootContainerInstance.child), + (newProps.memoizedProps = + rootContainerInstance.memoizedProps), + (newProps.memoizedState = + rootContainerInstance.memoizedState), + (newProps.updateQueue = + rootContainerInstance.updateQueue), + (type = rootContainerInstance.dependencies), + (newProps.dependencies = + null === type + ? null + : { + expirationTime: type.expirationTime, + firstContext: type.firstContext, + listeners: type.listeners, + responders: type.responders + })), + (renderExpirationTime$jscomp$0 = + renderExpirationTime$jscomp$0.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & + SubtreeSuspenseContextMask) | + ForceSuspenseFallback, + current$$1 + ); + current$$1 = current$$1.child; + break a; + } + current = current.sibling; + } + } + else { + if (!type) + if ( + ((current = findFirstSuspended(rootContainerInstance)), + null !== current) + ) { + if ( + ((current$$1.effectTag |= 64), + (type = !0), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && "hidden" === newProps.tailMode) + ) { + current = current.updateQueue; + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)); + current$$1 = current$$1.lastEffect = newProps.lastEffect; + null !== current$$1 && (current$$1.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((current$$1.effectTag |= 64), + (type = !0), + cutOffTailIfNeeded(newProps, !1), + (current$$1.expirationTime = current$$1.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((rootContainerInstance.sibling = current$$1.child), + (current$$1.child = rootContainerInstance)) + : ((current = newProps.last), + null !== current + ? (current.sibling = rootContainerInstance) + : (current$$1.child = rootContainerInstance), + (newProps.last = rootContainerInstance)); + } + if (null !== newProps.tail) { + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500); + current = newProps.tail; + newProps.rendering = current; + newProps.tail = current.sibling; + newProps.lastEffect = current$$1.lastEffect; + current.sibling = null; + renderExpirationTime$jscomp$0 = suspenseStackCursor.current; + renderExpirationTime$jscomp$0 = type + ? (renderExpirationTime$jscomp$0 & SubtreeSuspenseContextMask) | + ForceSuspenseFallback + : renderExpirationTime$jscomp$0 & SubtreeSuspenseContextMask; + push( + suspenseStackCursor, + renderExpirationTime$jscomp$0, + current$$1 + ); + current$$1 = current; + break a; + } break; case 20: break; default: throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } current$$1 = null; } current = workInProgress; if (1 === renderExpirationTime || 1 !== current.childExpirationTime) { - newProps = 0; - for ( - renderExpirationTime$jscomp$0 = current.child; - null !== renderExpirationTime$jscomp$0; - - ) - (type = renderExpirationTime$jscomp$0.expirationTime), - (rootContainerInstance = - renderExpirationTime$jscomp$0.childExpirationTime), - type > newProps && (newProps = type), - rootContainerInstance > newProps && - (newProps = rootContainerInstance), - (renderExpirationTime$jscomp$0 = - renderExpirationTime$jscomp$0.sibling); - current.childExpirationTime = newProps; + renderExpirationTime$jscomp$0 = 0; + for (newProps = current.child; null !== newProps; ) + (type = newProps.expirationTime), + (rootContainerInstance = newProps.childExpirationTime), + type > renderExpirationTime$jscomp$0 && + (renderExpirationTime$jscomp$0 = type), + rootContainerInstance > renderExpirationTime$jscomp$0 && + (renderExpirationTime$jscomp$0 = rootContainerInstance), + (newProps = newProps.sibling); + current.childExpirationTime = renderExpirationTime$jscomp$0; } if (null !== current$$1) return current$$1; null !== unitOfWork && @@ -5384,8 +6034,8 @@ function completeUnitOfWork(unitOfWork) { (workInProgressRootExitStatus = RootCompleted); return null; } -function commitRoot(root, expirationTime) { - runWithPriority(99, commitRootImpl.bind(null, root, expirationTime)); +function commitRoot(root) { + runWithPriority$1(99, commitRootImpl.bind(null, root)); null !== rootWithPendingPassiveEffects && ((root = getCurrentPriorityLevel()), scheduleCallback(root, function() { @@ -5394,13 +6044,21 @@ function commitRoot(root, expirationTime) { })); return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); - var finishedWork = root.current.alternate; - if (null === finishedWork) - throw ReactError("Should have a work-in-progress root."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); + var finishedWork = root.finishedWork, + expirationTime = root.finishedExpirationTime; + if (null === finishedWork) return null; + root.finishedWork = null; + root.finishedExpirationTime = 0; + if (finishedWork === root.current) + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); root.callbackNode = null; root.callbackExpirationTime = 0; var updateExpirationTimeBeforeCommit = finishedWork.expirationTime, @@ -5417,14 +6075,14 @@ function commitRootImpl(root, expirationTime) { 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (childExpirationTimeBeforeCommit = finishedWork.firstEffect)) - : (childExpirationTimeBeforeCommit = finishedWork) - : (childExpirationTimeBeforeCommit = finishedWork.firstEffect); - if (null !== childExpirationTimeBeforeCommit) { - updateExpirationTimeBeforeCommit = workPhase; - workPhase = CommitPhase; + (updateExpirationTimeBeforeCommit = finishedWork.firstEffect)) + : (updateExpirationTimeBeforeCommit = finishedWork) + : (updateExpirationTimeBeforeCommit = finishedWork.firstEffect); + if (null !== updateExpirationTimeBeforeCommit) { + childExpirationTimeBeforeCommit = executionContext; + executionContext |= CommitContext; ReactCurrentOwner$2.current = null; - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5467,11 +6125,12 @@ function commitRootImpl(root, expirationTime) { case 6: case 4: case 17: - case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5479,12 +6138,12 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5587,24 +6246,26 @@ function commitRootImpl(root, expirationTime) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; null !== alternate && ((alternate.return = null), (alternate.child = null), (alternate.memoizedState = null), - (alternate.updateQueue = null)); + (alternate.updateQueue = null), + (alternate.dependencies = null)); } nextEffect = nextEffect.nextEffect; } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); root.current = finishedWork; - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (effectTag = expirationTime; null !== nextEffect; ) { @@ -5679,7 +6340,9 @@ function commitRootImpl(root, expirationTime) { current$$1$jscomp$0.effectTag & 4 ) throw ReactError( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -5689,15 +6352,15 @@ function commitRootImpl(root, expirationTime) { case 12: break; case 13: + case 19: case 17: - break; case 20: break; - case 19: - break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5722,28 +6385,34 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); nextEffect = null; - workPhase = updateExpirationTimeBeforeCommit; + requestPaint(); + executionContext = childExpirationTimeBeforeCommit; } else root.current = finishedWork; - rootDoesHavePassiveEffects && - ((rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root)); - expirationTime = root.firstPendingTime; - 0 !== expirationTime - ? ((effectTag$jscomp$0 = requestCurrentTime()), - (effectTag$jscomp$0 = inferPriorityFromExpirationTime( - effectTag$jscomp$0, - expirationTime + if (rootDoesHavePassiveEffects) + (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root); + else + for (nextEffect = updateExpirationTimeBeforeCommit; null !== nextEffect; ) + (effectTag$jscomp$0 = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + (nextEffect = effectTag$jscomp$0); + effectTag$jscomp$0 = root.firstPendingTime; + 0 !== effectTag$jscomp$0 + ? ((current$$1$jscomp$1 = requestCurrentTime()), + (current$$1$jscomp$1 = inferPriorityFromExpirationTime( + current$$1$jscomp$1, + effectTag$jscomp$0 )), - scheduleCallbackForRoot(root, effectTag$jscomp$0, expirationTime)) + scheduleCallbackForRoot(root, current$$1$jscomp$1, effectTag$jscomp$0)) : (legacyErrorBoundariesThatAlreadyFailed = null); "function" === typeof onCommitFiberRoot && - onCommitFiberRoot(finishedWork.stateNode); - 1073741823 === expirationTime + onCommitFiberRoot(finishedWork.stateNode, expirationTime); + 1073741823 === effectTag$jscomp$0 ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -5753,31 +6422,42 @@ function commitRootImpl(root, expirationTime) { (root = firstUncaughtError), (firstUncaughtError = null), root); - if (workPhase === LegacyUnbatchedPhase) return null; - flushImmediateQueue(); + if ((executionContext & LegacyUnbatchedContext) !== NoContext) return null; + flushSyncCallbackQueue(); return null; } function flushPassiveEffects() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Cannot flush passive effects while already rendering."); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; for (root = root.current.firstEffect; null !== root; ) { try { var finishedWork = root; - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if (0 !== (finishedWork.effectTag & 512)) + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork), + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + } } catch (error) { - if (null === root) throw ReactError("Should be working on an effect."); + if (null === root) + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(root, error); } - root = root.nextEffect; + finishedWork = root.nextEffect; + root.nextEffect = null; + root = finishedWork; } - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); return !0; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -5818,11 +6498,18 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); workInProgressRoot === root && renderExpirationTime === suspendedTime - ? prepareFreshStack(root, renderExpirationTime) + ? workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ? prepareFreshStack(root, renderExpirationTime) + : (workInProgressRootHasPendingPing = !0) : root.lastPendingTime < suspendedTime || ((thenable = root.pingTime), (0 !== thenable && thenable < suspendedTime) || ((root.pingTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), (thenable = requestCurrentTime()), (thenable = inferPriorityFromExpirationTime(thenable, suspendedTime)), scheduleCallbackForRoot(root, thenable, suspendedTime))); @@ -5831,7 +6518,7 @@ function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(thenable); retryCache = requestCurrentTime(); - thenable = computeExpirationForFiber(retryCache, boundaryFiber); + thenable = computeExpirationForFiber(retryCache, boundaryFiber, null); retryCache = inferPriorityFromExpirationTime(retryCache, thenable); boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && @@ -5881,6 +6568,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, renderExpirationTime ); + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( current$$1, workInProgress, @@ -5888,6 +6580,39 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); return null !== workInProgress ? workInProgress.sibling : null; } + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); + break; + case 19: + updateExpirationTime = 0 !== (current$$1.effectTag & 64); + if (workInProgress.childExpirationTime < renderExpirationTime) + return ( + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ), + updateExpirationTime && (workInProgress.effectTag |= 64), + null + ); + if (updateExpirationTime) + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + updateExpirationTime = workInProgress.memoizedState; + null !== updateExpirationTime && + ((updateExpirationTime.rendering = null), + (updateExpirationTime.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); } return bailoutOnAlreadyFinishedWork( current$$1, @@ -6023,9 +6748,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { break; default: throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." + Error( + "Element type is invalid. Received a promise that resolves to: " + + context + + ". Lazy element type must resolve to a class or function." + ) ); } return workInProgress; @@ -6066,7 +6793,9 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime = workInProgress.updateQueue; if (null === updateExpirationTime) throw ReactError( - "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." + 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." + ) ); context = workInProgress.memoizedState; context = null !== context ? context.element : null; @@ -6221,16 +6950,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== oldValue; ) { - var list = oldValue.contextDependencies; + var list = oldValue.dependencies; if (null !== list) { getDerivedStateFromProps = oldValue.child; - for (var dependency = list.first; null !== dependency; ) { + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { if ( dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { 1 === oldValue.tag && - ((dependency = createUpdate(renderExpirationTime)), + ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), enqueueUpdate(oldValue, dependency)); oldValue.expirationTime < renderExpirationTime && @@ -6239,22 +6972,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); - dependency = renderExpirationTime; - for (var node = oldValue.return; null !== node; ) { - var alternate = node.alternate; - if (node.childExpirationTime < dependency) - (node.childExpirationTime = dependency), - null !== alternate && - alternate.childExpirationTime < dependency && - (alternate.childExpirationTime = dependency); - else if ( - null !== alternate && - alternate.childExpirationTime < dependency - ) - alternate.childExpirationTime = dependency; - else break; - node = node.return; - } + scheduleWorkOnParentPath( + oldValue.return, + renderExpirationTime + ); list.expirationTime < renderExpirationTime && (list.expirationTime = renderExpirationTime); break; @@ -6381,11 +7102,45 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ) ); + case 19: + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); }; +var onCommitFiberRoot = null, + onCommitFiberUnmount = null; +function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled || !hook.supportsFiber) return !0; + try { + var rendererID = hook.inject(internals); + onCommitFiberRoot = function(root) { + try { + hook.onCommitFiberRoot( + rendererID, + root, + void 0, + 64 === (root.current.effectTag & 64) + ); + } catch (err) {} + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) {} + }; + } catch (err) {} + return !0; +} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -6393,7 +7148,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.index = 0; this.ref = null; this.pendingProps = pendingProps; - this.contextDependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; + this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; this.effectTag = 0; this.lastEffect = this.firstEffect = this.nextEffect = null; @@ -6442,7 +7197,16 @@ function createWorkInProgress(current, pendingProps) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + pendingProps = current.dependencies; + workInProgress.dependencies = + null === pendingProps + ? null + : { + expirationTime: pendingProps.expirationTime, + firstContext: pendingProps.firstContext, + listeners: pendingProps.listeners, + responders: pendingProps.responders + }; workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; @@ -6470,12 +7234,16 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 3, expirationTime, key); + fiberTag = 8; + mode |= 7; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 2, expirationTime, key); + fiberTag = 8; + mode |= 1; + break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -6484,8 +7252,15 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.elementType = REACT_SUSPENSE_TYPE), (type.type = REACT_SUSPENSE_TYPE), + (type.elementType = REACT_SUSPENSE_TYPE), + (type.expirationTime = expirationTime), + type + ); + case REACT_SUSPENSE_LIST_TYPE: + return ( + (type = createFiber(19, pendingProps, key, mode)), + (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type ); @@ -6510,9 +7285,11 @@ function createFiberFromTypeAndProps( break a; } throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (null == type ? type : typeof type) + - "." + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (null == type ? type : typeof type) + + "." + ) ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -6526,14 +7303,6 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { elements.expirationTime = expirationTime; return elements; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - pendingProps = createFiber(8, pendingProps, key, mode); - mode = 0 === (mode & 1) ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; - pendingProps.elementType = mode; - pendingProps.type = mode; - pendingProps.expirationTime = expirationTime; - return pendingProps; -} function createFiberFromText(content, mode, expirationTime) { content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; @@ -6554,11 +7323,12 @@ function createFiberFromPortal(portal, mode, expirationTime) { }; return mode; } -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pingCache = this.pendingChildren = null; - this.pendingCommitExpirationTime = 0; + this.finishedExpirationTime = 0; this.finishedWork = null; this.timeoutHandle = -1; this.pendingContext = this.context = null; @@ -6570,10 +7340,12 @@ function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { if ("function" === typeof component.render) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } component = findCurrentHostFiber(fiber); @@ -6581,8 +7353,13 @@ function findHostInstance(component) { } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current, - currentTime = requestCurrentTime(); - current$$1 = computeExpirationForFiber(currentTime, current$$1); + currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + current$$1 = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); currentTime = container.current; a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; @@ -6592,7 +7369,9 @@ function updateContainer(element, container, parentComponent, callback) { 1 !== parentComponent.tag ) throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + 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 parentContext = parentComponent; do { @@ -6611,7 +7390,9 @@ function updateContainer(element, container, parentComponent, callback) { parentContext = parentContext.return; } while (null !== parentContext); throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (1 === parentComponent.tag) { @@ -6631,12 +7412,11 @@ function updateContainer(element, container, parentComponent, callback) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(current$$1); - callback.payload = { element: element }; + suspenseConfig = createUpdate(current$$1, suspenseConfig); + suspenseConfig.payload = { element: element }; container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - flushPassiveEffects(); - enqueueUpdate(currentTime, callback); + null !== container && (suspenseConfig.callback = container); + enqueueUpdate(currentTime, suspenseConfig); scheduleUpdateOnFiber(currentTime, current$$1); return current$$1; } @@ -6651,7 +7431,7 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } -function _inherits(subClass, superClass) { +function _inherits$1(subClass, superClass) { if ("function" !== typeof superClass && null !== superClass) throw new TypeError( "Super expression must either be null or a function, not " + @@ -6673,9 +7453,10 @@ function _inherits(subClass, superClass) { var getInspectorDataForViewTag = void 0; getInspectorDataForViewTag = function() { throw ReactError( - "getInspectorDataForViewTag() is not available in production" + Error("getInspectorDataForViewTag() is not available in production") ); }; +var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -6689,19 +7470,19 @@ function findNodeHandle(componentOrHandle) { ? componentOrHandle.canonical._nativeTag : componentOrHandle._nativeTag; } -_batchedUpdatesImpl = function(fn, a) { - if (0 !== workPhase) return fn(a); - workPhase = 1; +batchedUpdatesImpl = function(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= 1; try { return fn(a); } finally { - (workPhase = 0), flushImmediateQueue(); + (executionContext = prevExecutionContext), + executionContext === NoContext && flushSyncCallbackQueue(); } }; -_flushInteractiveUpdatesImpl = function() { - workPhase !== RenderPhase && - workPhase !== CommitPhase && - flushPendingDiscreteUpdates(); +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); }; var roots = new Map(), ReactFabric = { @@ -6720,7 +7501,7 @@ var roots = new Map(), ? this : call; } - _inherits(ReactNativeComponent, _React$Component); + _inherits$1(ReactNativeComponent, _React$Component); ReactNativeComponent.prototype.blur = function() { ReactNativePrivateInterface.TextInputState.blurTextInput( findNodeHandle(this) @@ -6816,10 +7597,19 @@ var roots = new Map(), })(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, setNativeProps: function() {}, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + null != handle._internalInstanceHandle && + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = new FiberRootNode(containerTag, !1); + root = new FiberRootNode(containerTag, 0, !1); var uninitializedFiber = createFiber(3, null, null, 0); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -6966,7 +7756,8 @@ var roots = new Map(), findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, - setRefreshHandler: null + setRefreshHandler: null, + getCurrentFiber: null }) ); })({ diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.js b/Libraries/Renderer/implementations/ReactFabric-prod.js index 1ac5cef90b4f53..88bd68a54c22b2 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -15,10 +15,9 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -function ReactError(message) { - message = Error(message); - message.name = "Invariant Violation"; - return message; +function ReactError(error) { + error.name = "Invariant Violation"; + return error; } var eventPluginOrder = null, namesToPlugins = {}; @@ -29,16 +28,20 @@ function recomputePluginOrdering() { pluginIndex = eventPluginOrder.indexOf(pluginName); if (!(-1 < pluginIndex)) throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); if (!plugins[pluginIndex]) { if (!pluginModule.extractEvents) throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); plugins[pluginIndex] = pluginModule; pluginIndex = pluginModule.eventTypes; @@ -49,9 +52,11 @@ function recomputePluginOrdering() { eventName$jscomp$0 = eventName; if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ) ); eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -77,11 +82,13 @@ function recomputePluginOrdering() { : (JSCompiler_inline_result = !1); if (!JSCompiler_inline_result) throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } } @@ -90,9 +97,11 @@ function recomputePluginOrdering() { function publishRegistrationName(registrationName, pluginModule) { if (registrationNameModules[registrationName]) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); registrationNameModules[registrationName] = pluginModule; } @@ -141,7 +150,9 @@ function invokeGuardedCallbackAndCatchFirstError( caughtError = null; } else throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } @@ -159,7 +170,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; if (Array.isArray(dispatchListener)) - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null; @@ -172,7 +183,9 @@ function executeDirectDispatch(event) { function accumulateInto(current, next) { if (null == next) throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); if (null == current) return next; if (Array.isArray(current)) { @@ -209,7 +222,9 @@ var injection = { injectEventPluginOrder: function(injectedEventPluginOrder) { if (eventPluginOrder) throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); @@ -226,9 +241,11 @@ var injection = { ) { if (namesToPlugins[pluginName]) throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); namesToPlugins[pluginName] = pluginModule; isOrderingDirty = !0; @@ -270,11 +287,13 @@ function getListener(inst, registrationName) { if (inst) return null; if (listener && "function" !== typeof listener) throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); return listener; } @@ -438,7 +457,9 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { if (!(event instanceof this)) throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); event.destructor(); 10 > this.eventPool.length && this.eventPool.push(event); @@ -474,7 +495,8 @@ function timestampForTouch(touch) { } function getTouchIdentifier(_ref) { _ref = _ref.identifier; - if (null == _ref) throw ReactError("Touch object is missing identifier."); + if (null == _ref) + throw ReactError(Error("Touch object is missing identifier.")); return _ref; } function recordTouchStart(touch) { @@ -517,7 +539,7 @@ function recordTouchMove(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch move without a touch start.\nTouch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -535,7 +557,7 @@ function recordTouchEnd(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch end without a touch start.\nTouch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -589,7 +611,7 @@ var ResponderTouchHistoryStore = { function accumulate(current, next) { if (null == next) throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error("accumulate(...): Accumulated items must not be null or undefined.") ); return null == current ? next @@ -967,7 +989,9 @@ injection.injectEventPluginsByName({ directDispatchConfig = customDirectEventTypes[topLevelType]; if (!bubbleDispatchConfig && !directDispatchConfig) throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); topLevelType = SyntheticEvent.getPooled( bubbleDispatchConfig || directDispatchConfig, @@ -993,7 +1017,7 @@ getFiberCurrentPropsFromNode = function(inst) { getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { inst = inst.stateNode.canonical._nativeTag; - if (!inst) throw ReactError("All native instances should have a tag."); + if (!inst) throw ReactError(Error("All native instances should have a tag.")); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1010,6 +1034,8 @@ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher") || (ReactSharedInternals.ReactCurrentDispatcher = { current: null }); +ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig") || + (ReactSharedInternals.ReactCurrentBatchConfig = { suspense: null }); var hasSymbol = "function" === typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, @@ -1023,11 +1049,13 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, + REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; -hasSymbol && Symbol.for("react.event_component"); -hasSymbol && Symbol.for("react.event_target"); -hasSymbol && Symbol.for("react.event_target.touch_hit"); +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; @@ -1041,8 +1069,6 @@ function getComponentName(type) { if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -1053,6 +1079,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1087,14 +1115,14 @@ function isFiberMountedImpl(fiber) { } function assertIsMounted(fiber) { if (2 !== isFiberMountedImpl(fiber)) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; if (!alternate) { alternate = isFiberMountedImpl(fiber); if (3 === alternate) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return 1 === alternate ? null : fiber; } for (var a = fiber, b = alternate; ; ) { @@ -1115,7 +1143,7 @@ function findCurrentFiberUsingSlowPath(fiber) { if (parentB === b) return assertIsMounted(parentA), alternate; parentB = parentB.sibling; } - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } if (a.return !== b.return) (a = parentA), (b = parentB); else { @@ -1152,17 +1180,21 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (!didFindChild) throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } } if (a.alternate !== b) throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (3 !== a.tag) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return a.stateNode.current === a ? fiber : alternate; } function findCurrentHostFiber(parent) { @@ -1415,23 +1447,28 @@ var restoreTarget = null, function restoreStateOfTarget(target) { if (getInstanceFromNode(target)) throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } -function _batchedUpdatesImpl(fn, bookkeeping) { +function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } -function _flushInteractiveUpdatesImpl() {} -var isBatching = !1; +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { - if (isBatching) return fn(bookkeeping); - isBatching = !0; + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - if (((isBatching = !1), null !== restoreTarget || null !== restoreQueue)) + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) if ( - (_flushInteractiveUpdatesImpl(), + (flushDiscreteUpdatesImpl(), restoreTarget && ((bookkeeping = restoreTarget), (fn = restoreQueue), @@ -1443,6 +1480,51 @@ function batchedUpdates(fn, bookkeeping) { restoreStateOfTarget(fn[bookkeeping]); } } +function _inherits(subClass, superClass) { + if ("function" !== typeof superClass && null !== superClass) + throw new TypeError( + "Super expression must either be null or a function, not " + + typeof superClass + ); + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: !1, + writable: !0, + configurable: !0 + } + }); + superClass && + (Object.setPrototypeOf + ? Object.setPrototypeOf(subClass, superClass) + : (subClass.__proto__ = superClass)); +} +(function(_React$Component) { + function ReactNativeComponent() { + if (!(this instanceof ReactNativeComponent)) + throw new TypeError("Cannot call a class as a function"); + var call = _React$Component.apply(this, arguments); + if (!this) + throw new ReferenceError( + "this hasn't been initialised - super() hasn't been called" + ); + return !call || ("object" !== typeof call && "function" !== typeof call) + ? this + : call; + } + _inherits(ReactNativeComponent, _React$Component); + ReactNativeComponent.prototype.blur = function() {}; + ReactNativeComponent.prototype.focus = function() {}; + ReactNativeComponent.prototype.measure = function() {}; + ReactNativeComponent.prototype.measureInWindow = function() {}; + ReactNativeComponent.prototype.measureLayout = function() {}; + ReactNativeComponent.prototype.setNativeProps = function() {}; + return ReactNativeComponent; +})(React.Component); +new Map(); +new Map(); +new Set(); +new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { batchedUpdates(function() { var events = nativeEvent.target; @@ -1465,7 +1547,9 @@ function dispatchEvent(target, topLevelType, nativeEvent) { forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); if (eventQueue) throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); if (hasRethrowError) throw ((events = rethrowError), @@ -1477,24 +1561,26 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } function shim$1() { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, +var _nativeFabricUIManage$1 = nativeFabricUIManager, + createNode = _nativeFabricUIManage$1.createNode, + cloneNode = _nativeFabricUIManage$1.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage$1.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, + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage$1.createChildSet, + appendChildNode = _nativeFabricUIManage$1.appendChild, + appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, + completeRoot = _nativeFabricUIManage$1.completeRoot, + registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, + fabricMeasure = _nativeFabricUIManage$1.measure, + fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1556,7 +1642,7 @@ function createTextInstance( ) { if (!hostContext.isInAParentText) throw ReactError( - "Text strings must be rendered within a component." + Error("Text strings must be rendered within a component.") ); hostContext = nextReactTag; nextReactTag += 2; @@ -1671,7 +1757,9 @@ function popTopLevelContextObject(fiber) { function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); @@ -1684,10 +1772,12 @@ function processChildContext(fiber, type, parentContext) { for (var contextKey in instance) if (!(contextKey in fiber)) throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); return Object.assign({}, parentContext, instance); } @@ -1709,7 +1799,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { var instance = workInProgress.stateNode; if (!instance) throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); didChange ? ((type = processChildContext(workInProgress, type, previousContext)), @@ -1720,38 +1812,11 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -var onCommitFiberRoot = null, - onCommitFiberUnmount = null; -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) {} - }; -} -function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - var rendererID = hook.inject(internals); - onCommitFiberRoot = catchErrors(function(root) { - hook.onCommitFiberRoot( - rendererID, - root, - void 0, - 64 === (root.current.effectTag & 64) - ); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) {} - return !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 = Scheduler.unstable_now, Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel, @@ -1761,10 +1826,11 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_LowPriority = Scheduler.unstable_LowPriority, Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, fakeCallbackNode = {}, - shouldYield = Scheduler.unstable_shouldYield, - immediateQueue = null, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, immediateQueueCallbackNode = null, - isFlushingImmediate = !1, + isFlushingSyncQueue = !1, initialTimeMs = Scheduler_now(), now = 1e4 > initialTimeMs @@ -1785,7 +1851,7 @@ function getCurrentPriorityLevel() { case Scheduler_IdlePriority: return 95; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function reactPriorityToSchedulerPriority(reactPriorityLevel) { @@ -1801,54 +1867,55 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case 95: return Scheduler_IdlePriority; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (99 === reactPriorityLevel) - return ( - null === immediateQueue - ? ((immediateQueue = [callback]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ))) - : immediateQueue.push(callback), - fakeCallbackNode - ); reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function flushImmediateQueue() { +function scheduleSyncCallback(callback) { + null === syncQueue + ? ((syncQueue = [callback]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(callback); + return fakeCallbackNode; +} +function flushSyncCallbackQueue() { null !== immediateQueueCallbackNode && Scheduler_cancelCallback(immediateQueueCallbackNode); - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && null !== immediateQueue) { - isFlushingImmediate = !0; +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; var i = 0; try { - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do callback = callback(!0); - while (null !== callback); - } - immediateQueue = null; + var queue = syncQueue; + runWithPriority$1(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; } catch (error) { - throw (null !== immediateQueue && - (immediateQueue = immediateQueue.slice(i + 1)), + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ), error); } finally { - isFlushingImmediate = !1; + isFlushingSyncQueue = !1; } } } @@ -1856,7 +1923,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (1073741823 === expirationTime) return 99; if (1 === expirationTime) return 95; currentTime = - 10 * (1073741822 - expirationTime) - 10 * (1073741822 - currentTime); + 10 * (1073741821 - expirationTime) - 10 * (1073741821 - currentTime); return 0 >= currentTime ? 99 : 250 >= currentTime @@ -1938,7 +2005,7 @@ var valueCursor = { current: null }, currentlyRenderingFiber = null, lastContextDependency = null, lastContextWithAllBitsObserved = null; -function resetContextDependences() { +function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } function pushProvider(providerFiber, nextValue) { @@ -1951,14 +2018,32 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); providerFiber.type._context._currentValue2 = currentValue; } +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + for (; null !== parent; ) { + var alternate = parent.alternate; + if (parent.childExpirationTime < renderExpirationTime) + (parent.childExpirationTime = renderExpirationTime), + null !== alternate && + alternate.childExpirationTime < renderExpirationTime && + (alternate.childExpirationTime = renderExpirationTime); + else if ( + null !== alternate && + alternate.childExpirationTime < renderExpirationTime + ) + alternate.childExpirationTime = renderExpirationTime; + else break; + parent = parent.return; + } +} function prepareToReadContext(workInProgress, renderExpirationTime) { currentlyRenderingFiber = workInProgress; lastContextWithAllBitsObserved = lastContextDependency = null; - var currentDependencies = workInProgress.contextDependencies; - null !== currentDependencies && - currentDependencies.expirationTime >= renderExpirationTime && - (didReceiveUpdate = !0); - workInProgress.contextDependencies = null; + workInProgress = workInProgress.dependencies; + null !== workInProgress && + null !== workInProgress.firstContext && + (workInProgress.expirationTime >= renderExpirationTime && + (didReceiveUpdate = !0), + (workInProgress.firstContext = null)); } function readContext(context, observedBits) { if ( @@ -1972,12 +2057,16 @@ function readContext(context, observedBits) { if (null === lastContextDependency) { if (null === currentlyRenderingFiber) throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); lastContextDependency = observedBits; - currentlyRenderingFiber.contextDependencies = { - first: observedBits, - expirationTime: 0 + currentlyRenderingFiber.dependencies = { + expirationTime: 0, + firstContext: observedBits, + listeners: null, + responders: null }; } else lastContextDependency = lastContextDependency.next = observedBits; } @@ -2010,9 +2099,10 @@ function cloneUpdateQueue(currentQueue) { lastCapturedEffect: null }; } -function createUpdate(expirationTime) { +function createUpdate(expirationTime, suspenseConfig) { return { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, @@ -2128,8 +2218,10 @@ function processUpdateQueue( ((newFirstUpdate = update), (newBaseState = resultState)), newExpirationTime < updateExpirationTime && (newExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), (resultState = getStateFromUpdate( workInProgress, queue, @@ -2205,15 +2297,18 @@ function commitUpdateEffects(effect, instance) { var context = instance; if ("function" !== typeof _callback3) throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - _callback3 + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + _callback3 + ) ); _callback3.call(context); } effect = effect.nextEffect; } } -var emptyRefsObject = new React.Component().refs; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + emptyRefsObject = new React.Component().refs; function applyDerivedStateFromProps( workInProgress, ctor, @@ -2240,36 +2335,42 @@ var classComponentUpdater = { }, enqueueSetState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 1; + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 2; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 2; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); } }; @@ -2398,15 +2499,19 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); inst = element.stateNode; } if (!inst) throw ReactError( - "Missing owner for string ref " + - returnFiber + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + returnFiber + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); var stringRef = "" + returnFiber; if ( @@ -2426,13 +2531,17 @@ function coerceRef(returnFiber, current$$1, element) { } if ("string" !== typeof returnFiber) throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); if (!element._owner) throw ReactError( - "Element ref was specified as a string (" + - returnFiber + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + returnFiber + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } return returnFiber; @@ -2440,11 +2549,13 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) throw ReactError( - "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === Object.prototype.toString.call(newChild) + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + ) ); } function ChildReconciler(shouldTrackSideEffects) { @@ -2847,11 +2958,13 @@ function ChildReconciler(shouldTrackSideEffects) { var iteratorFn = getIteratorFn(newChildrenIterable); if ("function" !== typeof iteratorFn) throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); newChildrenIterable = iteratorFn.call(newChildrenIterable); if (null == newChildrenIterable) - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); for ( var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, @@ -3086,8 +3199,10 @@ function ChildReconciler(shouldTrackSideEffects) { case 0: throw ((returnFiber = returnFiber.type), ReactError( - (returnFiber.displayName || returnFiber.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (returnFiber.displayName || returnFiber.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) )); } return deleteRemainingChildren(returnFiber, currentFirstChild); @@ -3102,7 +3217,9 @@ var reconcileChildFibers = ChildReconciler(!0), function requiredContext(c) { if (c === NO_CONTEXT) throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); return c; } @@ -3140,6 +3257,50 @@ function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } +var SubtreeSuspenseContextMask = 1, + InvisibleParentSuspenseContext = 1, + ForceSuspenseFallback = 2, + suspenseStackCursor = { current: 0 }; +function findFirstSuspended(row) { + for (var node = row; null !== node; ) { + if (13 === node.tag) { + if (null !== node.memoizedState) return node; + } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { + if (0 !== (node.effectTag & 64)) return node; + } else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; +} +var currentListenerHookIndex = 0; +function updateListenerHook(responder, props) { + var dependencies = null.dependencies; + null === dependencies && + (dependencies = null.dependencies = { + expirationTime: 0, + firstContext: null, + listeners: [], + responders: null + }); + var listeners = dependencies.listeners; + null === listeners && (dependencies.listeners = listeners = []); + listeners.length === currentListenerHookIndex + ? (listeners.push({ responder: responder, props: props }), + currentListenerHookIndex++) + : ((listeners = listeners[currentListenerHookIndex++]), + (listeners.responder = responder), + (listeners.props = props)); +} var NoEffect$1 = 0, UnmountSnapshot = 2, UnmountMutation = 4, @@ -3164,7 +3325,9 @@ var NoEffect$1 = 0, numberOfReRenders = 0; function throwInvalidHookError() { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } function areHookInputsEqual(nextDeps, prevDeps) { @@ -3214,7 +3377,9 @@ function renderWithHooks( sideEffectTag = 0; if (current) throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); return workInProgress; } @@ -3250,7 +3415,9 @@ function updateWorkInProgressHook() { (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) - throw ReactError("Rendered more hooks than during the previous render."); + throw ReactError( + Error("Rendered more hooks than during the previous render.") + ); currentHook = nextCurrentHook; var newHook = { memoizedState: currentHook.memoizedState, @@ -3275,7 +3442,9 @@ function updateReducer(reducer) { queue = hook.queue; if (null === queue) throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); queue.lastRenderedReducer = reducer; if (0 < numberOfReRenders) { @@ -3318,8 +3487,10 @@ function updateReducer(reducer) { (firstRenderPhaseUpdate = newState)), updateExpirationTime > remainingExpirationTime && (remainingExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ), (newState = _update.eagerReducer === reducer ? _update.eagerState @@ -3398,7 +3569,9 @@ function mountDebugValue() {} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); var alternate = fiber.alternate; if ( @@ -3409,6 +3582,7 @@ function dispatchAction(fiber, queue, action) { ((didScheduleRenderPhaseUpdate = !0), (fiber = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, @@ -3424,24 +3598,29 @@ function dispatchAction(fiber, queue, action) { queue.next = fiber; } else { - flushPassiveEffects(); - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, fiber); - var _update2 = { - expirationTime: currentTime, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }, - _last = queue.last; - if (null === _last) _update2.next = _update2; + var currentTime = requestCurrentTime(), + _suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); + _suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: _suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var _last = queue.last; + if (null === _last) _suspenseConfig.next = _suspenseConfig; else { var first = _last.next; - null !== first && (_update2.next = first); - _last.next = _update2; + null !== first && (_suspenseConfig.next = first); + _last.next = _suspenseConfig; } - queue.last = _update2; + queue.last = _suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3450,8 +3629,8 @@ function dispatchAction(fiber, queue, action) { try { var currentState = queue.lastRenderedState, _eagerState = alternate(currentState, action); - _update2.eagerReducer = alternate; - _update2.eagerState = _eagerState; + _suspenseConfig.eagerReducer = alternate; + _suspenseConfig.eagerState = _eagerState; if (is(_eagerState, currentState)) return; } catch (error) { } finally { @@ -3470,7 +3649,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3543,7 +3723,8 @@ var ContextOnlyDispatcher = { ); return [hook.memoizedState, initialState]; }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, HooksDispatcherOnUpdate = { readContext: readContext, @@ -3597,7 +3778,8 @@ var ContextOnlyDispatcher = { useState: function(initialState) { return updateReducer(basicStateReducer, initialState); }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, hydrationParentFiber = null, nextHydratableInstance = null, @@ -4138,6 +4320,7 @@ function pushHostRootContext(workInProgress) { pushTopLevelContextObject(workInProgress, root.context, !1); pushHostContainer(workInProgress, root.containerInfo); } +var SUSPENDED_MARKER = {}; function updateSuspenseComponent( current$$1, workInProgress, @@ -4145,100 +4328,271 @@ function updateSuspenseComponent( ) { var mode = workInProgress.mode, nextProps = workInProgress.pendingProps, - nextState = workInProgress.memoizedState; - if (0 === (workInProgress.effectTag & 64)) { - nextState = null; - var nextDidTimeout = !1; - } else - (nextState = { - fallbackExpirationTime: - null !== nextState ? nextState.fallbackExpirationTime : 0 - }), + suspenseContext = suspenseStackCursor.current, + nextState = null, + nextDidTimeout = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || + (JSCompiler_temp = + 0 !== (suspenseContext & ForceSuspenseFallback) && + (null === current$$1 || null !== current$$1.memoizedState)); + JSCompiler_temp + ? ((nextState = SUSPENDED_MARKER), (nextDidTimeout = !0), - (workInProgress.effectTag &= -65); + (workInProgress.effectTag &= -65)) + : (null !== current$$1 && null === current$$1.memoizedState) || + void 0 === nextProps.fallback || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= InvisibleParentSuspenseContext); + suspenseContext &= SubtreeSuspenseContextMask; + push(suspenseStackCursor, suspenseContext, workInProgress); if (null === current$$1) if (nextDidTimeout) { - var nextFallbackChildren = nextProps.fallback; + nextProps = nextProps.fallback; current$$1 = createFiberFromFragment(null, mode, 0, null); - 0 === (workInProgress.mode & 1) && - (current$$1.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child); - mode = createFiberFromFragment( - nextFallbackChildren, + current$$1.return = workInProgress; + if (0 === (workInProgress.mode & 2)) + for ( + nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + current$$1.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = current$$1), + (nextDidTimeout = nextDidTimeout.sibling); + renderExpirationTime = createFiberFromFragment( + nextProps, mode, renderExpirationTime, null ); - current$$1.sibling = mode; - renderExpirationTime = current$$1; - renderExpirationTime.return = mode.return = workInProgress; + renderExpirationTime.return = workInProgress; + current$$1.sibling = renderExpirationTime; + mode = current$$1; } else - renderExpirationTime = mode = mountChildFibers( + mode = renderExpirationTime = mountChildFibers( workInProgress, null, nextProps.children, renderExpirationTime ); - else - null !== current$$1.memoizedState - ? ((mode = current$$1.child), - (nextFallbackChildren = mode.sibling), - nextDidTimeout - ? ((renderExpirationTime = nextProps.fallback), - (nextProps = createWorkInProgress(mode, mode.pendingProps, 0)), - 0 === (workInProgress.mode & 1) && - ((nextDidTimeout = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child), - nextDidTimeout !== mode.child && - (nextProps.child = nextDidTimeout)), - (mode = nextProps.sibling = createWorkInProgress( - nextFallbackChildren, - renderExpirationTime, - nextFallbackChildren.expirationTime - )), - (renderExpirationTime = nextProps), - (nextProps.childExpirationTime = 0), - (renderExpirationTime.return = mode.return = workInProgress)) - : (renderExpirationTime = mode = reconcileChildFibers( - workInProgress, - mode.child, - nextProps.children, - renderExpirationTime - ))) - : ((nextFallbackChildren = current$$1.child), - nextDidTimeout - ? ((nextDidTimeout = nextProps.fallback), - (nextProps = createFiberFromFragment(null, mode, 0, null)), - (nextProps.child = nextFallbackChildren), - 0 === (workInProgress.mode & 1) && - (nextProps.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child), - (mode = nextProps.sibling = createFiberFromFragment( - nextDidTimeout, - mode, - renderExpirationTime, - null - )), - (mode.effectTag |= 2), - (renderExpirationTime = nextProps), - (nextProps.childExpirationTime = 0), - (renderExpirationTime.return = mode.return = workInProgress)) - : (mode = renderExpirationTime = reconcileChildFibers( - workInProgress, - nextFallbackChildren, - nextProps.children, - renderExpirationTime - ))), - (workInProgress.stateNode = current$$1.stateNode); + else { + if (null !== current$$1.memoizedState) + if ( + ((suspenseContext = current$$1.child), + (mode = suspenseContext.sibling), + nextDidTimeout) + ) { + nextProps = nextProps.fallback; + renderExpirationTime = createWorkInProgress( + suspenseContext, + suspenseContext.pendingProps, + 0 + ); + renderExpirationTime.return = workInProgress; + if ( + 0 === (workInProgress.mode & 2) && + ((nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child), + nextDidTimeout !== suspenseContext.child) + ) + for ( + renderExpirationTime.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = renderExpirationTime), + (nextDidTimeout = nextDidTimeout.sibling); + nextProps = createWorkInProgress(mode, nextProps, mode.expirationTime); + nextProps.return = workInProgress; + renderExpirationTime.sibling = nextProps; + mode = renderExpirationTime; + renderExpirationTime.childExpirationTime = 0; + renderExpirationTime = nextProps; + } else + mode = renderExpirationTime = reconcileChildFibers( + workInProgress, + suspenseContext.child, + nextProps.children, + renderExpirationTime + ); + else if (((suspenseContext = current$$1.child), nextDidTimeout)) { + nextDidTimeout = nextProps.fallback; + nextProps = createFiberFromFragment(null, mode, 0, null); + nextProps.return = workInProgress; + nextProps.child = suspenseContext; + null !== suspenseContext && (suspenseContext.return = nextProps); + if (0 === (workInProgress.mode & 2)) + for ( + suspenseContext = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + nextProps.child = suspenseContext; + null !== suspenseContext; + + ) + (suspenseContext.return = nextProps), + (suspenseContext = suspenseContext.sibling); + renderExpirationTime = createFiberFromFragment( + nextDidTimeout, + mode, + renderExpirationTime, + null + ); + renderExpirationTime.return = workInProgress; + nextProps.sibling = renderExpirationTime; + renderExpirationTime.effectTag |= 2; + mode = nextProps; + nextProps.childExpirationTime = 0; + } else + renderExpirationTime = mode = reconcileChildFibers( + workInProgress, + suspenseContext, + nextProps.children, + renderExpirationTime + ); + workInProgress.stateNode = current$$1.stateNode; + } workInProgress.memoizedState = nextState; - workInProgress.child = renderExpirationTime; - return mode; + workInProgress.child = mode; + return renderExpirationTime; +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailExpiration = 0), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren( + current$$1, + workInProgress, + nextProps.children, + renderExpirationTime + ); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & ForceSuspenseFallback)) + (nextProps = + (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), + (workInProgress.effectTag |= 64); + else { + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) { + if (null !== current$$1.memoizedState) { + current$$1.expirationTime < renderExpirationTime && + (current$$1.expirationTime = renderExpirationTime); + var alternate = current$$1.alternate; + null !== alternate && + alternate.expirationTime < renderExpirationTime && + (alternate.expirationTime = renderExpirationTime); + scheduleWorkOnParentPath(current$$1.return, renderExpirationTime); + } + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) + break a; + current$$1 = current$$1.return; + } + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + nextProps &= SubtreeSuspenseContextMask; + } + push(suspenseStackCursor, nextProps, workInProgress); + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderExpirationTime = workInProgress.child; + for (revealOrder = null; null !== renderExpirationTime; ) + (nextProps = renderExpirationTime.alternate), + null !== nextProps && + null === findFirstSuspended(nextProps) && + (revealOrder = renderExpirationTime), + (renderExpirationTime = renderExpirationTime.sibling); + renderExpirationTime = revealOrder; + null === renderExpirationTime + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderExpirationTime.sibling), + (renderExpirationTime.sibling = null)); + initSuspenseListRenderState( + workInProgress, + !1, + revealOrder, + renderExpirationTime, + tailMode + ); + break; + case "backwards": + renderExpirationTime = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + nextProps = revealOrder.alternate; + if (null !== nextProps && null === findFirstSuspended(nextProps)) { + workInProgress.child = revealOrder; + break; + } + nextProps = revealOrder.sibling; + revealOrder.sibling = renderExpirationTime; + renderExpirationTime = revealOrder; + revealOrder = nextProps; + } + initSuspenseListRenderState( + workInProgress, + !0, + renderExpirationTime, + null, + tailMode + ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; + } + return workInProgress.child; } function bailoutOnAlreadyFinishedWork( current$$1, @@ -4246,10 +4600,10 @@ function bailoutOnAlreadyFinishedWork( renderExpirationTime ) { null !== current$$1 && - (workInProgress.contextDependencies = current$$1.contextDependencies); + (workInProgress.dependencies = current$$1.dependencies); if (workInProgress.childExpirationTime < renderExpirationTime) return null; if (null !== current$$1 && workInProgress.child !== current$$1.child) - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); if (null !== workInProgress.child) { current$$1 = workInProgress.child; renderExpirationTime = createWorkInProgress( @@ -4460,6 +4814,74 @@ updateHostText$1 = function(current, workInProgress, oldText, newText) { )), (workInProgress.effectTag |= 4)); }; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var _lastTailNode = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === _lastTailNode + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (_lastTailNode.sibling = null); + } +} +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + workInProgress.effectTag = (effectTag & -2049) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null + ); + case 18: + return null; + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} function createCapturedValue(value, source) { return { value: value, @@ -4467,24 +4889,18 @@ function createCapturedValue(value, source) { stack: getStackByFiberInDevAndProd(source) }; } +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") + ); function logCapturedError(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - if (error instanceof Error) { - capturedError = error.message; - var name = error.name; - try { - error.message = - (capturedError ? name + ": " + capturedError : name) + - "\n\nThis error is located at:" + - componentStack; - } catch (e) {} - } else - error = - "string" === typeof error - ? Error(error + "\n\nThis error is located at:" + componentStack) - : Error("Unspecified error at:" + componentStack); - ReactNativePrivateInterface.ExceptionsManager.handleException(error, !1); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ) && console.error(capturedError.error); } var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; function logError(boundary, errorInfo) { @@ -4555,7 +4971,12 @@ function commitWork(current$$1, finishedWork) { case 12: return; case 13: - commitSuspenseComponent(finishedWork); + null !== finishedWork.memoizedState && + (globalMostRecentFallbackTime = now()); + attachSuspenseRetryListeners(finishedWork); + return; + case 19: + attachSuspenseRetryListeners(finishedWork); return; } switch (finishedWork.tag) { @@ -4563,29 +4984,26 @@ function commitWork(current$$1, finishedWork) { case 5: case 6: case 20: - case 19: break; case 3: case 4: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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 commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; - null !== newState && - 0 === newState.fallbackExpirationTime && - (newState.fallbackExpirationTime = requestCurrentTime() - 500); - newState = finishedWork.updateQueue; - if (null !== newState) { +function attachSuspenseRetryListeners(finishedWork) { + var thenables = finishedWork.updateQueue; + if (null !== thenables) { finishedWork.updateQueue = null; var retryCache = finishedWork.stateNode; null === retryCache && (retryCache = finishedWork.stateNode = new PossiblyWeakSet$1()); - newState.forEach(function(thenable) { + thenables.forEach(function(thenable) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); retryCache.has(thenable) || (retryCache.add(thenable), thenable.then(retry, retry)); @@ -4594,7 +5012,7 @@ function commitSuspenseComponent(finishedWork) { } var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; expirationTime.payload = { element: null }; var error = errorInfo.value; @@ -4605,7 +5023,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { @@ -4631,64 +5049,29 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { }); return expirationTime; } -function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null; - case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -2049) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: - return ( - (effectTag = workInProgress.effectTag), - effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null - ); - case 18: - return null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 19: - case 20: - return null; - default: - return null; - } -} var ceil = Math.ceil, ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - LegacyUnbatchedPhase = 2, - RenderPhase = 4, - CommitPhase = 5, + NoContext = 0, + LegacyUnbatchedContext = 8, + RenderContext = 16, + CommitContext = 32, RootIncomplete = 0, RootErrored = 1, RootSuspended = 2, - RootCompleted = 3, - workPhase = 0, + RootSuspendedWithDelay = 3, + RootCompleted = 4, + executionContext = NoContext, workInProgressRoot = null, workInProgress = null, renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, - workInProgressRootMostRecentEventTime = 1073741823, + workInProgressRootLatestProcessedExpirationTime = 1073741823, + workInProgressRootLatestSuspenseTimeout = 1073741823, + workInProgressRootCanSuspendUsingConfig = null, + workInProgressRootHasPendingPing = !1, + globalMostRecentFallbackTime = 0, + FALLBACK_THROTTLE_MS = 500, nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, @@ -4700,34 +5083,49 @@ var ceil = Math.ceil, rootWithNestedUpdates = null, currentEventTime = 0; function requestCurrentTime() { - return workPhase === RenderPhase || workPhase === CommitPhase - ? 1073741822 - ((now() / 10) | 0) + return (executionContext & (RenderContext | CommitContext)) !== NoContext + ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime ? currentEventTime - : (currentEventTime = 1073741822 - ((now() / 10) | 0)); -} -function computeExpirationForFiber(currentTime, fiber) { - if (0 === (fiber.mode & 1)) return 1073741823; - if (workPhase === RenderPhase) return renderExpirationTime; - switch (getCurrentPriorityLevel()) { - case 99: - currentTime = 1073741823; - break; - case 98: - currentTime = - 1073741822 - 10 * ((((1073741822 - currentTime + 15) / 10) | 0) + 1); - break; - case 97: - case 96: - currentTime = - 1073741822 - 25 * ((((1073741822 - currentTime + 500) / 25) | 0) + 1); - break; - case 95: - currentTime = 1; - break; - default: - throw ReactError("Expected a valid priority level"); - } + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); +} +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + fiber = fiber.mode; + if (0 === (fiber & 2)) return 1073741823; + var priorityLevel = getCurrentPriorityLevel(); + if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; + if ((executionContext & RenderContext) !== NoContext) + return renderExpirationTime; + if (null !== suspenseConfig) + currentTime = + 1073741821 - + 25 * + ((((1073741821 - + currentTime + + (suspenseConfig.timeoutMs | 0 || 5e3) / 10) / + 25) | + 0) + + 1); + else + switch (priorityLevel) { + case 99: + currentTime = 1073741823; + break; + case 98: + currentTime = + 1073741821 - 10 * ((((1073741821 - currentTime + 15) / 10) | 0) + 1); + break; + case 97: + case 96: + currentTime = + 1073741821 - 25 * ((((1073741821 - currentTime + 500) / 25) | 0) + 1); + break; + case 95: + currentTime = 1; + break; + default: + throw ReactError(Error("Expected a valid priority level")); + } null !== workInProgressRoot && currentTime === renderExpirationTime && --currentTime; @@ -4738,33 +5136,37 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) )); fiber = markUpdateTimeFromFiberToRoot(fiber, expirationTime); - if (null !== fiber) - if (((fiber.pingTime = 0), 1073741823 === expirationTime)) - if (workPhase === LegacyUnbatchedPhase) + if (null !== fiber) { + fiber.pingTime = 0; + var priorityLevel = getCurrentPriorityLevel(); + if (1073741823 === expirationTime) + if ( + (executionContext & LegacyUnbatchedContext) !== NoContext && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) for ( - expirationTime = renderRoot(fiber, 1073741823, !0); - null !== expirationTime; + var callback = renderRoot(fiber, 1073741823, !0); + null !== callback; ) - expirationTime = expirationTime(!0); + callback = callback(!0); else scheduleCallbackForRoot(fiber, 99, 1073741823), - 0 === workPhase && flushImmediateQueue(); - else { - var priorityLevel = getCurrentPriorityLevel(); - if (98 === priorityLevel) - if (null === rootsWithPendingDiscreteUpdates) - rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]]); - else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(fiber); - (void 0 === lastDiscreteTime || lastDiscreteTime > expirationTime) && - rootsWithPendingDiscreteUpdates.set(fiber, expirationTime); - } - scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); - } + executionContext === NoContext && flushSyncCallbackQueue(); + else scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); + (executionContext & 4) === NoContext || + (98 !== priorityLevel && 99 !== priorityLevel) || + (null === rootsWithPendingDiscreteUpdates + ? (rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]])) + : ((priorityLevel = rootsWithPendingDiscreteUpdates.get(fiber)), + (void 0 === priorityLevel || priorityLevel > expirationTime) && + rootsWithPendingDiscreteUpdates.set(fiber, expirationTime))); + } } function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { fiber.expirationTime < expirationTime && @@ -4805,21 +5207,28 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode); root.callbackExpirationTime = expirationTime; - existingCallbackNode = null; - 1073741823 !== expirationTime && - 1 !== expirationTime && - ((existingCallbackNode = 10 * (1073741822 - expirationTime) - now()), - 5e3 < existingCallbackNode && (existingCallbackNode = 5e3), - (existingCallbackNode = { timeout: existingCallbackNode })); - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - existingCallbackNode - ); + 1073741823 === expirationTime + ? (root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + )) + : ((existingCallbackNode = null), + 1 !== expirationTime && + (existingCallbackNode = { + timeout: 10 * (1073741821 - expirationTime) - now() + }), + (root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + existingCallbackNode + ))); } } function runRootCallback(root, callback, isSync) { @@ -4843,9 +5252,7 @@ function resolveLocksOnRoot(root, expirationTime) { return null !== firstBatch && firstBatch._defer && firstBatch._expirationTime >= expirationTime - ? ((root.finishedWork = root.current.alternate), - (root.pendingCommitExpirationTime = expirationTime), - scheduleCallback(97, function() { + ? (scheduleCallback(97, function() { firstBatch._onComplete(); return null; }), @@ -4857,13 +5264,14 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback(99, renderRoot.bind(null, root, expirationTime)); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = 0; + root.finishedWork = null; + root.finishedExpirationTime = 0; var timeoutHandle = root.timeoutHandle; -1 !== timeoutHandle && ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); @@ -4887,6 +5295,12 @@ function prepareFreshStack(root, expirationTime) { case 4: popHostContainer(interruptedWork); break; + case 13: + pop(suspenseStackCursor, interruptedWork); + break; + case 19: + pop(suspenseStackCursor, interruptedWork); + break; case 10: popProvider(interruptedWork); } @@ -4896,24 +5310,33 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = 1073741823; + workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = !1; } function renderRoot(root$jscomp$0, expirationTime, isSync) { - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); if (root$jscomp$0.firstPendingTime < expirationTime) return null; - if (root$jscomp$0.pendingCommitExpirationTime === expirationTime) - return ( - (root$jscomp$0.pendingCommitExpirationTime = 0), - commitRoot.bind(null, root$jscomp$0, expirationTime) - ); + if (isSync && root$jscomp$0.finishedExpirationTime === expirationTime) + return commitRoot.bind(null, root$jscomp$0); flushPassiveEffects(); - (root$jscomp$0 === workInProgressRoot && - expirationTime === renderExpirationTime) || + if ( + root$jscomp$0 !== workInProgressRoot || + expirationTime !== renderExpirationTime + ) prepareFreshStack(root$jscomp$0, expirationTime); + else if (workInProgressRootExitStatus === RootSuspendedWithDelay) + if (workInProgressRootHasPendingPing) + prepareFreshStack(root$jscomp$0, expirationTime); + else { + var lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + } if (null !== workInProgress) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + lastPendingTime = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; null === prevDispatcher && (prevDispatcher = ContextOnlyDispatcher); ReactCurrentDispatcher.current = ContextOnlyDispatcher; @@ -4922,8 +5345,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) return ( - (workPhase = prevWorkPhase), - resetContextDependences(), + (executionContext = lastPendingTime), + resetContextDependencies(), (ReactCurrentDispatcher.current = prevDispatcher), renderRoot.bind(null, root$jscomp$0, currentTime) ); @@ -4935,16 +5358,16 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); else - for (; null !== workInProgress && !shouldYield(); ) + for (; null !== workInProgress && !Scheduler_shouldYield(); ) workInProgress = performUnitOfWork(workInProgress); break; } catch (thrownValue) { - resetContextDependences(); + resetContextDependencies(); resetHooks(); currentTime = workInProgress; if (null === currentTime || null === currentTime.return) throw (prepareFreshStack(root$jscomp$0, expirationTime), - (workPhase = prevWorkPhase), + (executionContext = lastPendingTime), thrownValue); a: { var root = root$jscomp$0, @@ -4959,29 +5382,41 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; + var thenable = value, + hasInvisibleParentBoundary = + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext); value = returnFiber; do { - if ( - 13 === value.tag && - (void 0 === value.memoizedProps.fallback - ? 0 - : null === value.memoizedState) - ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === value.tag)) + null !== value.memoizedState + ? (JSCompiler_temp = !1) + : ((JSCompiler_temp = value.memoizedProps), + (JSCompiler_temp = + void 0 === JSCompiler_temp.fallback + ? !1 + : !0 !== JSCompiler_temp.unstable_avoidThisFallback + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0)); + if (JSCompiler_temp) { returnFiber = value.updateQueue; null === returnFiber ? ((returnFiber = new Set()), returnFiber.add(thenable), (value.updateQueue = returnFiber)) : returnFiber.add(thenable); - if (0 === (value.mode & 1)) { + if (0 === (value.mode & 2)) { value.effectTag |= 64; sourceFiber.effectTag &= -1957; 1 === sourceFiber.tag && (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((renderExpirationTime$jscomp$0 = createUpdate( - 1073741823 + 1073741823, + null )), (renderExpirationTime$jscomp$0.tag = 2), enqueueUpdate( @@ -4993,15 +5428,15 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { } sourceFiber = root; root = renderExpirationTime$jscomp$0; - var pingCache = sourceFiber.pingCache; - null === pingCache - ? ((pingCache = sourceFiber.pingCache = new PossiblyWeakMap()), + hasInvisibleParentBoundary = sourceFiber.pingCache; + null === hasInvisibleParentBoundary + ? ((hasInvisibleParentBoundary = sourceFiber.pingCache = new PossiblyWeakMap()), (returnFiber = new Set()), - pingCache.set(thenable, returnFiber)) - : ((returnFiber = pingCache.get(thenable)), + hasInvisibleParentBoundary.set(thenable, returnFiber)) + : ((returnFiber = hasInvisibleParentBoundary.get(thenable)), void 0 === returnFiber && ((returnFiber = new Set()), - pingCache.set(thenable, returnFiber))); + hasInvisibleParentBoundary.set(thenable, returnFiber))); returnFiber.has(root) || (returnFiber.add(root), (sourceFiber = pingSuspendedRoot.bind( @@ -5023,11 +5458,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { getStackByFiberInDevAndProd(sourceFiber) ); } - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootErrored; + workInProgressRootExitStatus !== RootCompleted && + (workInProgressRootExitStatus = RootErrored); value = createCapturedValue(value, sourceFiber); sourceFiber = returnFiber; do { @@ -5079,76 +5511,144 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = completeUnitOfWork(currentTime); } while (1); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = lastPendingTime; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (null !== workInProgress) return renderRoot.bind(null, root$jscomp$0, expirationTime); } + root$jscomp$0.finishedWork = root$jscomp$0.current.alternate; + root$jscomp$0.finishedExpirationTime = expirationTime; if (resolveLocksOnRoot(root$jscomp$0, expirationTime)) return null; workInProgressRoot = null; switch (workInProgressRootExitStatus) { case RootIncomplete: - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); case RootErrored: return ( - (prevWorkPhase = root$jscomp$0.lastPendingTime), - root$jscomp$0.lastPendingTime < expirationTime - ? renderRoot.bind(null, root$jscomp$0, prevWorkPhase) + (lastPendingTime = root$jscomp$0.lastPendingTime), + lastPendingTime < expirationTime + ? renderRoot.bind(null, root$jscomp$0, lastPendingTime) : isSync - ? commitRoot.bind(null, root$jscomp$0, expirationTime) + ? commitRoot.bind(null, root$jscomp$0) : (prepareFreshStack(root$jscomp$0, expirationTime), - scheduleCallback( - 99, + scheduleSyncCallback( renderRoot.bind(null, root$jscomp$0, expirationTime) ), null) ); case RootSuspended: + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + !isSync && + ((isSync = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < isSync) + ) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); + lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + isSync + ); + return null; + } + return commitRoot.bind(null, root$jscomp$0); + case RootSuspendedWithDelay: if (!isSync) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); isSync = root$jscomp$0.lastPendingTime; - if (root$jscomp$0.lastPendingTime < expirationTime) + if (isSync < expirationTime) return renderRoot.bind(null, root$jscomp$0, isSync); - if ( - 1073741823 !== workInProgressRootMostRecentEventTime && - ((prevWorkPhase = - 10 * (1073741822 - workInProgressRootMostRecentEventTime) - 5e3), - (isSync = now()), - (prevWorkPhase = isSync - prevWorkPhase), - (prevWorkPhase = - (120 > prevWorkPhase - ? 120 - : 480 > prevWorkPhase - ? 480 - : 1080 > prevWorkPhase - ? 1080 - : 1920 > prevWorkPhase - ? 1920 - : 3e3 > prevWorkPhase - ? 3e3 - : 4320 > prevWorkPhase - ? 4320 - : 1960 * ceil(prevWorkPhase / 1960)) - prevWorkPhase), - (isSync = 10 * (1073741822 - expirationTime) - isSync), - isSync < prevWorkPhase && (prevWorkPhase = isSync), - (isSync = prevWorkPhase), - 10 < isSync) - ) + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (isSync = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (isSync = 0) + : ((isSync = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (lastPendingTime = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - lastPendingTime), + (isSync = lastPendingTime - isSync), + 0 > isSync && (isSync = 0), + (isSync = + (120 > isSync + ? 120 + : 480 > isSync + ? 480 + : 1080 > isSync + ? 1080 + : 1920 > isSync + ? 1920 + : 3e3 > isSync + ? 3e3 + : 4320 > isSync + ? 4320 + : 1960 * ceil(isSync / 1960)) - isSync), + expirationTime < isSync && (isSync = expirationTime)); + if (10 < isSync) return ( (root$jscomp$0.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root$jscomp$0, expirationTime), + commitRoot.bind(null, root$jscomp$0), isSync )), null ); } - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return commitRoot.bind(null, root$jscomp$0); case RootCompleted: - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return !isSync && + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig && + ((lastPendingTime = workInProgressRootLatestProcessedExpirationTime), + (prevDispatcher = workInProgressRootCanSuspendUsingConfig), + (expirationTime = prevDispatcher.busyMinDurationMs | 0), + 0 >= expirationTime + ? (expirationTime = 0) + : ((isSync = prevDispatcher.busyDelayMs | 0), + (lastPendingTime = + now() - + (10 * (1073741821 - lastPendingTime) - + (prevDispatcher.timeoutMs | 0 || 5e3))), + (expirationTime = + lastPendingTime <= isSync + ? 0 + : isSync + expirationTime - lastPendingTime)), + 10 < expirationTime) + ? ((root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + expirationTime + )), + null) + : commitRoot.bind(null, root$jscomp$0); default: - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } } +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 1 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 1 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} function performUnitOfWork(unitOfWork) { var next = beginWork$$1( unitOfWork.alternate, @@ -5185,10 +5685,11 @@ function completeUnitOfWork(unitOfWork) { case 3: popHostContainer(current$$1); popTopLevelContextObject(current$$1); - newProps = current$$1.stateNode; - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)); + renderExpirationTime$jscomp$0 = current$$1.stateNode; + renderExpirationTime$jscomp$0.pendingContext && + ((renderExpirationTime$jscomp$0.context = + renderExpirationTime$jscomp$0.pendingContext), + (renderExpirationTime$jscomp$0.pendingContext = null)); if (null === current || null === current.child) current$$1.effectTag &= -3; updateHostContainer(current$$1); @@ -5212,8 +5713,8 @@ function completeUnitOfWork(unitOfWork) { requiredContext(contextStackCursor$1.current); current = newProps; var rootContainerInstance = renderExpirationTime$jscomp$0; - newProps = current$$1; - renderExpirationTime$jscomp$0 = nextReactTag; + renderExpirationTime$jscomp$0 = current$$1; + newProps = nextReactTag; nextReactTag += 2; type = getViewConfigForType(type); var updatePayload = diffProperties( @@ -5223,17 +5724,17 @@ function completeUnitOfWork(unitOfWork) { type.validAttributes ); rootContainerInstance = createNode( - renderExpirationTime$jscomp$0, + newProps, type.uiViewClassName, rootContainerInstance, updatePayload, - newProps + renderExpirationTime$jscomp$0 ); current = new ReactFabricHostComponent( - renderExpirationTime$jscomp$0, + newProps, type, current, - newProps + renderExpirationTime$jscomp$0 ); current = { node: rootContainerInstance, canonical: current }; appendAllChildren(current, current$$1, !1, !1); @@ -5241,7 +5742,9 @@ function completeUnitOfWork(unitOfWork) { null !== current$$1.ref && (current$$1.effectTag |= 128); } else if (null === current$$1.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -5255,7 +5758,9 @@ function completeUnitOfWork(unitOfWork) { else { if ("string" !== typeof newProps && null === current$$1.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); current = requiredContext(rootInstanceStackCursor.current); renderExpirationTime$jscomp$0 = requiredContext( @@ -5272,36 +5777,47 @@ function completeUnitOfWork(unitOfWork) { case 11: break; case 13: + pop(suspenseStackCursor, current$$1); newProps = current$$1.memoizedState; if (0 !== (current$$1.effectTag & 64)) { current$$1.expirationTime = renderExpirationTime$jscomp$0; break a; } - newProps = null !== newProps; - renderExpirationTime$jscomp$0 = !1; + renderExpirationTime$jscomp$0 = null !== newProps; + newProps = !1; null !== current && ((type = current.memoizedState), - (renderExpirationTime$jscomp$0 = null !== type), - newProps || + (newProps = null !== type), + renderExpirationTime$jscomp$0 || null === type || - ((type = type.fallbackExpirationTime), - type < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = type), - (current = current.child.sibling), - null !== current && - ((type = current$$1.firstEffect), - null !== type - ? ((current$$1.firstEffect = current), - (current.nextEffect = type)) - : ((current$$1.firstEffect = current$$1.lastEffect = current), - (current.nextEffect = null)), - (current.effectTag = 8)))); - newProps && - !renderExpirationTime$jscomp$0 && - 0 !== (current$$1.mode & 1) && - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - newProps && (current$$1.effectTag |= 4); + ((type = current.child.sibling), + null !== type && + ((rootContainerInstance = current$$1.firstEffect), + null !== rootContainerInstance + ? ((current$$1.firstEffect = type), + (type.nextEffect = rootContainerInstance)) + : ((current$$1.firstEffect = current$$1.lastEffect = type), + (type.nextEffect = null)), + (type.effectTag = 8)))); + if ( + renderExpirationTime$jscomp$0 && + !newProps && + 0 !== (current$$1.mode & 2) + ) + if ( + (null === current && + !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + renderExpirationTime$jscomp$0 && (current$$1.effectTag |= 4); break; case 7: break; @@ -5326,33 +5842,167 @@ function completeUnitOfWork(unitOfWork) { case 18: break; case 19: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (null === newProps) break; + type = 0 !== (current$$1.effectTag & 64); + rootContainerInstance = newProps.rendering; + if (null === rootContainerInstance) + if (type) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = current$$1.child; null !== current; ) { + rootContainerInstance = findFirstSuspended(current); + if (null !== rootContainerInstance) { + current$$1.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = rootContainerInstance.updateQueue; + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)); + current$$1.firstEffect = current$$1.lastEffect = null; + current = renderExpirationTime$jscomp$0; + for ( + renderExpirationTime$jscomp$0 = current$$1.child; + null !== renderExpirationTime$jscomp$0; + + ) + (newProps = renderExpirationTime$jscomp$0), + (type = current), + (newProps.effectTag &= 2), + (newProps.nextEffect = null), + (newProps.firstEffect = null), + (newProps.lastEffect = null), + (rootContainerInstance = newProps.alternate), + null === rootContainerInstance + ? ((newProps.childExpirationTime = 0), + (newProps.expirationTime = type), + (newProps.child = null), + (newProps.memoizedProps = null), + (newProps.memoizedState = null), + (newProps.updateQueue = null), + (newProps.dependencies = null)) + : ((newProps.childExpirationTime = + rootContainerInstance.childExpirationTime), + (newProps.expirationTime = + rootContainerInstance.expirationTime), + (newProps.child = rootContainerInstance.child), + (newProps.memoizedProps = + rootContainerInstance.memoizedProps), + (newProps.memoizedState = + rootContainerInstance.memoizedState), + (newProps.updateQueue = + rootContainerInstance.updateQueue), + (type = rootContainerInstance.dependencies), + (newProps.dependencies = + null === type + ? null + : { + expirationTime: type.expirationTime, + firstContext: type.firstContext, + listeners: type.listeners, + responders: type.responders + })), + (renderExpirationTime$jscomp$0 = + renderExpirationTime$jscomp$0.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & + SubtreeSuspenseContextMask) | + ForceSuspenseFallback, + current$$1 + ); + current$$1 = current$$1.child; + break a; + } + current = current.sibling; + } + } + else { + if (!type) + if ( + ((current = findFirstSuspended(rootContainerInstance)), + null !== current) + ) { + if ( + ((current$$1.effectTag |= 64), + (type = !0), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && "hidden" === newProps.tailMode) + ) { + current = current.updateQueue; + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)); + current$$1 = current$$1.lastEffect = newProps.lastEffect; + null !== current$$1 && (current$$1.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((current$$1.effectTag |= 64), + (type = !0), + cutOffTailIfNeeded(newProps, !1), + (current$$1.expirationTime = current$$1.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((rootContainerInstance.sibling = current$$1.child), + (current$$1.child = rootContainerInstance)) + : ((current = newProps.last), + null !== current + ? (current.sibling = rootContainerInstance) + : (current$$1.child = rootContainerInstance), + (newProps.last = rootContainerInstance)); + } + if (null !== newProps.tail) { + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500); + current = newProps.tail; + newProps.rendering = current; + newProps.tail = current.sibling; + newProps.lastEffect = current$$1.lastEffect; + current.sibling = null; + renderExpirationTime$jscomp$0 = suspenseStackCursor.current; + renderExpirationTime$jscomp$0 = type + ? (renderExpirationTime$jscomp$0 & SubtreeSuspenseContextMask) | + ForceSuspenseFallback + : renderExpirationTime$jscomp$0 & SubtreeSuspenseContextMask; + push( + suspenseStackCursor, + renderExpirationTime$jscomp$0, + current$$1 + ); + current$$1 = current; + break a; + } break; case 20: break; default: throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } current$$1 = null; } current = workInProgress; if (1 === renderExpirationTime || 1 !== current.childExpirationTime) { - newProps = 0; - for ( - renderExpirationTime$jscomp$0 = current.child; - null !== renderExpirationTime$jscomp$0; - - ) - (type = renderExpirationTime$jscomp$0.expirationTime), - (rootContainerInstance = - renderExpirationTime$jscomp$0.childExpirationTime), - type > newProps && (newProps = type), - rootContainerInstance > newProps && - (newProps = rootContainerInstance), - (renderExpirationTime$jscomp$0 = - renderExpirationTime$jscomp$0.sibling); - current.childExpirationTime = newProps; + renderExpirationTime$jscomp$0 = 0; + for (newProps = current.child; null !== newProps; ) + (type = newProps.expirationTime), + (rootContainerInstance = newProps.childExpirationTime), + type > renderExpirationTime$jscomp$0 && + (renderExpirationTime$jscomp$0 = type), + rootContainerInstance > renderExpirationTime$jscomp$0 && + (renderExpirationTime$jscomp$0 = rootContainerInstance), + (newProps = newProps.sibling); + current.childExpirationTime = renderExpirationTime$jscomp$0; } if (null !== current$$1) return current$$1; null !== unitOfWork && @@ -5384,8 +6034,8 @@ function completeUnitOfWork(unitOfWork) { (workInProgressRootExitStatus = RootCompleted); return null; } -function commitRoot(root, expirationTime) { - runWithPriority(99, commitRootImpl.bind(null, root, expirationTime)); +function commitRoot(root) { + runWithPriority$1(99, commitRootImpl.bind(null, root)); null !== rootWithPendingPassiveEffects && ((root = getCurrentPriorityLevel()), scheduleCallback(root, function() { @@ -5394,13 +6044,21 @@ function commitRoot(root, expirationTime) { })); return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); - var finishedWork = root.current.alternate; - if (null === finishedWork) - throw ReactError("Should have a work-in-progress root."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); + var finishedWork = root.finishedWork, + expirationTime = root.finishedExpirationTime; + if (null === finishedWork) return null; + root.finishedWork = null; + root.finishedExpirationTime = 0; + if (finishedWork === root.current) + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); root.callbackNode = null; root.callbackExpirationTime = 0; var updateExpirationTimeBeforeCommit = finishedWork.expirationTime, @@ -5417,14 +6075,14 @@ function commitRootImpl(root, expirationTime) { 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (childExpirationTimeBeforeCommit = finishedWork.firstEffect)) - : (childExpirationTimeBeforeCommit = finishedWork) - : (childExpirationTimeBeforeCommit = finishedWork.firstEffect); - if (null !== childExpirationTimeBeforeCommit) { - updateExpirationTimeBeforeCommit = workPhase; - workPhase = CommitPhase; + (updateExpirationTimeBeforeCommit = finishedWork.firstEffect)) + : (updateExpirationTimeBeforeCommit = finishedWork) + : (updateExpirationTimeBeforeCommit = finishedWork.firstEffect); + if (null !== updateExpirationTimeBeforeCommit) { + childExpirationTimeBeforeCommit = executionContext; + executionContext |= CommitContext; ReactCurrentOwner$2.current = null; - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5467,11 +6125,12 @@ function commitRootImpl(root, expirationTime) { case 6: case 4: case 17: - case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5479,12 +6138,12 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5587,24 +6246,26 @@ function commitRootImpl(root, expirationTime) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; null !== alternate && ((alternate.return = null), (alternate.child = null), (alternate.memoizedState = null), - (alternate.updateQueue = null)); + (alternate.updateQueue = null), + (alternate.dependencies = null)); } nextEffect = nextEffect.nextEffect; } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); root.current = finishedWork; - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (effectTag = expirationTime; null !== nextEffect; ) { @@ -5679,7 +6340,9 @@ function commitRootImpl(root, expirationTime) { current$$1$jscomp$0.effectTag & 4 ) throw ReactError( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -5689,15 +6352,15 @@ function commitRootImpl(root, expirationTime) { case 12: break; case 13: + case 19: case 17: - break; case 20: break; - case 19: - break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5722,28 +6385,34 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); nextEffect = null; - workPhase = updateExpirationTimeBeforeCommit; + requestPaint(); + executionContext = childExpirationTimeBeforeCommit; } else root.current = finishedWork; - rootDoesHavePassiveEffects && - ((rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root)); - expirationTime = root.firstPendingTime; - 0 !== expirationTime - ? ((effectTag$jscomp$0 = requestCurrentTime()), - (effectTag$jscomp$0 = inferPriorityFromExpirationTime( - effectTag$jscomp$0, - expirationTime + if (rootDoesHavePassiveEffects) + (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root); + else + for (nextEffect = updateExpirationTimeBeforeCommit; null !== nextEffect; ) + (effectTag$jscomp$0 = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + (nextEffect = effectTag$jscomp$0); + effectTag$jscomp$0 = root.firstPendingTime; + 0 !== effectTag$jscomp$0 + ? ((current$$1$jscomp$1 = requestCurrentTime()), + (current$$1$jscomp$1 = inferPriorityFromExpirationTime( + current$$1$jscomp$1, + effectTag$jscomp$0 )), - scheduleCallbackForRoot(root, effectTag$jscomp$0, expirationTime)) + scheduleCallbackForRoot(root, current$$1$jscomp$1, effectTag$jscomp$0)) : (legacyErrorBoundariesThatAlreadyFailed = null); "function" === typeof onCommitFiberRoot && - onCommitFiberRoot(finishedWork.stateNode); - 1073741823 === expirationTime + onCommitFiberRoot(finishedWork.stateNode, expirationTime); + 1073741823 === effectTag$jscomp$0 ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -5753,31 +6422,42 @@ function commitRootImpl(root, expirationTime) { (root = firstUncaughtError), (firstUncaughtError = null), root); - if (workPhase === LegacyUnbatchedPhase) return null; - flushImmediateQueue(); + if ((executionContext & LegacyUnbatchedContext) !== NoContext) return null; + flushSyncCallbackQueue(); return null; } function flushPassiveEffects() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Cannot flush passive effects while already rendering."); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; for (root = root.current.firstEffect; null !== root; ) { try { var finishedWork = root; - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if (0 !== (finishedWork.effectTag & 512)) + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork), + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + } } catch (error) { - if (null === root) throw ReactError("Should be working on an effect."); + if (null === root) + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(root, error); } - root = root.nextEffect; + finishedWork = root.nextEffect; + root.nextEffect = null; + root = finishedWork; } - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); return !0; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -5818,11 +6498,18 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); workInProgressRoot === root && renderExpirationTime === suspendedTime - ? prepareFreshStack(root, renderExpirationTime) + ? workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ? prepareFreshStack(root, renderExpirationTime) + : (workInProgressRootHasPendingPing = !0) : root.lastPendingTime < suspendedTime || ((thenable = root.pingTime), (0 !== thenable && thenable < suspendedTime) || ((root.pingTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), (thenable = requestCurrentTime()), (thenable = inferPriorityFromExpirationTime(thenable, suspendedTime)), scheduleCallbackForRoot(root, thenable, suspendedTime))); @@ -5831,7 +6518,7 @@ function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(thenable); retryCache = requestCurrentTime(); - thenable = computeExpirationForFiber(retryCache, boundaryFiber); + thenable = computeExpirationForFiber(retryCache, boundaryFiber, null); retryCache = inferPriorityFromExpirationTime(retryCache, thenable); boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && @@ -5881,6 +6568,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, renderExpirationTime ); + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( current$$1, workInProgress, @@ -5888,6 +6580,39 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); return null !== workInProgress ? workInProgress.sibling : null; } + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); + break; + case 19: + updateExpirationTime = 0 !== (current$$1.effectTag & 64); + if (workInProgress.childExpirationTime < renderExpirationTime) + return ( + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ), + updateExpirationTime && (workInProgress.effectTag |= 64), + null + ); + if (updateExpirationTime) + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + updateExpirationTime = workInProgress.memoizedState; + null !== updateExpirationTime && + ((updateExpirationTime.rendering = null), + (updateExpirationTime.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); } return bailoutOnAlreadyFinishedWork( current$$1, @@ -6023,9 +6748,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { break; default: throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." + Error( + "Element type is invalid. Received a promise that resolves to: " + + context + + ". Lazy element type must resolve to a class or function." + ) ); } return workInProgress; @@ -6066,7 +6793,9 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime = workInProgress.updateQueue; if (null === updateExpirationTime) throw ReactError( - "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." + 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." + ) ); context = workInProgress.memoizedState; context = null !== context ? context.element : null; @@ -6221,16 +6950,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== oldValue; ) { - var list = oldValue.contextDependencies; + var list = oldValue.dependencies; if (null !== list) { getDerivedStateFromProps = oldValue.child; - for (var dependency = list.first; null !== dependency; ) { + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { if ( dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { 1 === oldValue.tag && - ((dependency = createUpdate(renderExpirationTime)), + ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), enqueueUpdate(oldValue, dependency)); oldValue.expirationTime < renderExpirationTime && @@ -6239,22 +6972,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); - dependency = renderExpirationTime; - for (var node = oldValue.return; null !== node; ) { - var alternate = node.alternate; - if (node.childExpirationTime < dependency) - (node.childExpirationTime = dependency), - null !== alternate && - alternate.childExpirationTime < dependency && - (alternate.childExpirationTime = dependency); - else if ( - null !== alternate && - alternate.childExpirationTime < dependency - ) - alternate.childExpirationTime = dependency; - else break; - node = node.return; - } + scheduleWorkOnParentPath( + oldValue.return, + renderExpirationTime + ); list.expirationTime < renderExpirationTime && (list.expirationTime = renderExpirationTime); break; @@ -6381,11 +7102,45 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ) ); + case 19: + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); }; +var onCommitFiberRoot = null, + onCommitFiberUnmount = null; +function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled || !hook.supportsFiber) return !0; + try { + var rendererID = hook.inject(internals); + onCommitFiberRoot = function(root) { + try { + hook.onCommitFiberRoot( + rendererID, + root, + void 0, + 64 === (root.current.effectTag & 64) + ); + } catch (err) {} + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) {} + }; + } catch (err) {} + return !0; +} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -6393,7 +7148,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.index = 0; this.ref = null; this.pendingProps = pendingProps; - this.contextDependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; + this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; this.effectTag = 0; this.lastEffect = this.firstEffect = this.nextEffect = null; @@ -6442,7 +7197,16 @@ function createWorkInProgress(current, pendingProps) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + pendingProps = current.dependencies; + workInProgress.dependencies = + null === pendingProps + ? null + : { + expirationTime: pendingProps.expirationTime, + firstContext: pendingProps.firstContext, + listeners: pendingProps.listeners, + responders: pendingProps.responders + }; workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; @@ -6470,12 +7234,16 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 3, expirationTime, key); + fiberTag = 8; + mode |= 7; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 2, expirationTime, key); + fiberTag = 8; + mode |= 1; + break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -6484,8 +7252,15 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.elementType = REACT_SUSPENSE_TYPE), (type.type = REACT_SUSPENSE_TYPE), + (type.elementType = REACT_SUSPENSE_TYPE), + (type.expirationTime = expirationTime), + type + ); + case REACT_SUSPENSE_LIST_TYPE: + return ( + (type = createFiber(19, pendingProps, key, mode)), + (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type ); @@ -6510,9 +7285,11 @@ function createFiberFromTypeAndProps( break a; } throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (null == type ? type : typeof type) + - "." + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (null == type ? type : typeof type) + + "." + ) ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -6526,14 +7303,6 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { elements.expirationTime = expirationTime; return elements; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - pendingProps = createFiber(8, pendingProps, key, mode); - mode = 0 === (mode & 1) ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; - pendingProps.elementType = mode; - pendingProps.type = mode; - pendingProps.expirationTime = expirationTime; - return pendingProps; -} function createFiberFromText(content, mode, expirationTime) { content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; @@ -6554,11 +7323,12 @@ function createFiberFromPortal(portal, mode, expirationTime) { }; return mode; } -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pingCache = this.pendingChildren = null; - this.pendingCommitExpirationTime = 0; + this.finishedExpirationTime = 0; this.finishedWork = null; this.timeoutHandle = -1; this.pendingContext = this.context = null; @@ -6570,10 +7340,12 @@ function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { if ("function" === typeof component.render) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } component = findCurrentHostFiber(fiber); @@ -6581,8 +7353,13 @@ function findHostInstance(component) { } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current, - currentTime = requestCurrentTime(); - current$$1 = computeExpirationForFiber(currentTime, current$$1); + currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + current$$1 = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); currentTime = container.current; a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; @@ -6592,7 +7369,9 @@ function updateContainer(element, container, parentComponent, callback) { 1 !== parentComponent.tag ) throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + 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 parentContext = parentComponent; do { @@ -6611,7 +7390,9 @@ function updateContainer(element, container, parentComponent, callback) { parentContext = parentContext.return; } while (null !== parentContext); throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (1 === parentComponent.tag) { @@ -6631,12 +7412,11 @@ function updateContainer(element, container, parentComponent, callback) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(current$$1); - callback.payload = { element: element }; + suspenseConfig = createUpdate(current$$1, suspenseConfig); + suspenseConfig.payload = { element: element }; container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - flushPassiveEffects(); - enqueueUpdate(currentTime, callback); + null !== container && (suspenseConfig.callback = container); + enqueueUpdate(currentTime, suspenseConfig); scheduleUpdateOnFiber(currentTime, current$$1); return current$$1; } @@ -6651,7 +7431,7 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } -function _inherits(subClass, superClass) { +function _inherits$1(subClass, superClass) { if ("function" !== typeof superClass && null !== superClass) throw new TypeError( "Super expression must either be null or a function, not " + @@ -6673,9 +7453,10 @@ function _inherits(subClass, superClass) { var getInspectorDataForViewTag = void 0; getInspectorDataForViewTag = function() { throw ReactError( - "getInspectorDataForViewTag() is not available in production" + Error("getInspectorDataForViewTag() is not available in production") ); }; +var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -6689,19 +7470,19 @@ function findNodeHandle(componentOrHandle) { ? componentOrHandle.canonical._nativeTag : componentOrHandle._nativeTag; } -_batchedUpdatesImpl = function(fn, a) { - if (0 !== workPhase) return fn(a); - workPhase = 1; +batchedUpdatesImpl = function(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= 1; try { return fn(a); } finally { - (workPhase = 0), flushImmediateQueue(); + (executionContext = prevExecutionContext), + executionContext === NoContext && flushSyncCallbackQueue(); } }; -_flushInteractiveUpdatesImpl = function() { - workPhase !== RenderPhase && - workPhase !== CommitPhase && - flushPendingDiscreteUpdates(); +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); }; var roots = new Map(), ReactFabric = { @@ -6720,7 +7501,7 @@ var roots = new Map(), ? this : call; } - _inherits(ReactNativeComponent, _React$Component); + _inherits$1(ReactNativeComponent, _React$Component); ReactNativeComponent.prototype.blur = function() { ReactNativePrivateInterface.TextInputState.blurTextInput( findNodeHandle(this) @@ -6816,10 +7597,19 @@ var roots = new Map(), })(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, setNativeProps: function() {}, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + null != handle._internalInstanceHandle && + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = new FiberRootNode(containerTag, !1); + root = new FiberRootNode(containerTag, 0, !1); var uninitializedFiber = createFiber(3, null, null, 0); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -6966,7 +7756,8 @@ var roots = new Map(), findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, - setRefreshHandler: null + setRefreshHandler: null, + getCurrentFiber: null }) ); })({ diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 8f44f7111e6b0c..c4f8f3fd2b1ee8 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -15,10 +15,9 @@ var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/R React = require("react"), Scheduler = require("scheduler"), tracing = require("scheduler/tracing"); -function ReactError(message) { - message = Error(message); - message.name = "Invariant Violation"; - return message; +function ReactError(error) { + error.name = "Invariant Violation"; + return error; } var eventPluginOrder = null, namesToPlugins = {}; @@ -29,16 +28,20 @@ function recomputePluginOrdering() { pluginIndex = eventPluginOrder.indexOf(pluginName); if (!(-1 < pluginIndex)) throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); if (!plugins[pluginIndex]) { if (!pluginModule.extractEvents) throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); plugins[pluginIndex] = pluginModule; pluginIndex = pluginModule.eventTypes; @@ -49,9 +52,11 @@ function recomputePluginOrdering() { eventName$jscomp$0 = eventName; if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ) ); eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -77,11 +82,13 @@ function recomputePluginOrdering() { : (JSCompiler_inline_result = !1); if (!JSCompiler_inline_result) throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } } @@ -90,9 +97,11 @@ function recomputePluginOrdering() { function publishRegistrationName(registrationName, pluginModule) { if (registrationNameModules[registrationName]) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); registrationNameModules[registrationName] = pluginModule; } @@ -141,7 +150,9 @@ function invokeGuardedCallbackAndCatchFirstError( caughtError = null; } else throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } @@ -159,7 +170,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; if (Array.isArray(dispatchListener)) - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null; @@ -172,7 +183,9 @@ function executeDirectDispatch(event) { function accumulateInto(current, next) { if (null == next) throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); if (null == current) return next; if (Array.isArray(current)) { @@ -209,7 +222,9 @@ var injection = { injectEventPluginOrder: function(injectedEventPluginOrder) { if (eventPluginOrder) throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); @@ -226,9 +241,11 @@ var injection = { ) { if (namesToPlugins[pluginName]) throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); namesToPlugins[pluginName] = pluginModule; isOrderingDirty = !0; @@ -270,11 +287,13 @@ function getListener(inst, registrationName) { if (inst) return null; if (listener && "function" !== typeof listener) throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); return listener; } @@ -438,7 +457,9 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { if (!(event instanceof this)) throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); event.destructor(); 10 > this.eventPool.length && this.eventPool.push(event); @@ -474,7 +495,8 @@ function timestampForTouch(touch) { } function getTouchIdentifier(_ref) { _ref = _ref.identifier; - if (null == _ref) throw ReactError("Touch object is missing identifier."); + if (null == _ref) + throw ReactError(Error("Touch object is missing identifier.")); return _ref; } function recordTouchStart(touch) { @@ -517,7 +539,7 @@ function recordTouchMove(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch move without a touch start.\nTouch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -535,7 +557,7 @@ function recordTouchEnd(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch end without a touch start.\nTouch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -589,7 +611,7 @@ var ResponderTouchHistoryStore = { function accumulate(current, next) { if (null == next) throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error("accumulate(...): Accumulated items must not be null or undefined.") ); return null == current ? next @@ -967,7 +989,9 @@ injection.injectEventPluginsByName({ directDispatchConfig = customDirectEventTypes[topLevelType]; if (!bubbleDispatchConfig && !directDispatchConfig) throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); topLevelType = SyntheticEvent.getPooled( bubbleDispatchConfig || directDispatchConfig, @@ -993,7 +1017,7 @@ getFiberCurrentPropsFromNode = function(inst) { getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { inst = inst.stateNode.canonical._nativeTag; - if (!inst) throw ReactError("All native instances should have a tag."); + if (!inst) throw ReactError(Error("All native instances should have a tag.")); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1010,6 +1034,8 @@ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher") || (ReactSharedInternals.ReactCurrentDispatcher = { current: null }); +ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig") || + (ReactSharedInternals.ReactCurrentBatchConfig = { suspense: null }); var hasSymbol = "function" === typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, @@ -1023,11 +1049,13 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, + REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; -hasSymbol && Symbol.for("react.event_component"); -hasSymbol && Symbol.for("react.event_target"); -hasSymbol && Symbol.for("react.event_target.touch_hit"); +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; @@ -1036,14 +1064,11 @@ function getIteratorFn(maybeIterable) { maybeIterable["@@iterator"]; return "function" === typeof maybeIterable ? maybeIterable : null; } -require("../shims/ReactFeatureFlags"); function getComponentName(type) { if (null == type) return null; if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -1054,6 +1079,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1088,14 +1115,14 @@ function isFiberMountedImpl(fiber) { } function assertIsMounted(fiber) { if (2 !== isFiberMountedImpl(fiber)) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; if (!alternate) { alternate = isFiberMountedImpl(fiber); if (3 === alternate) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return 1 === alternate ? null : fiber; } for (var a = fiber, b = alternate; ; ) { @@ -1116,7 +1143,7 @@ function findCurrentFiberUsingSlowPath(fiber) { if (parentB === b) return assertIsMounted(parentA), alternate; parentB = parentB.sibling; } - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } if (a.return !== b.return) (a = parentA), (b = parentB); else { @@ -1153,17 +1180,21 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (!didFindChild) throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } } if (a.alternate !== b) throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (3 !== a.tag) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return a.stateNode.current === a ? fiber : alternate; } function findCurrentHostFiber(parent) { @@ -1416,23 +1447,29 @@ var restoreTarget = null, function restoreStateOfTarget(target) { if (getInstanceFromNode(target)) throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } -function _batchedUpdatesImpl(fn, bookkeeping) { +require("../shims/ReactFeatureFlags"); +function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } -function _flushInteractiveUpdatesImpl() {} -var isBatching = !1; +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { - if (isBatching) return fn(bookkeeping); - isBatching = !0; + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - if (((isBatching = !1), null !== restoreTarget || null !== restoreQueue)) + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) if ( - (_flushInteractiveUpdatesImpl(), + (flushDiscreteUpdatesImpl(), restoreTarget && ((bookkeeping = restoreTarget), (fn = restoreQueue), @@ -1444,6 +1481,51 @@ function batchedUpdates(fn, bookkeeping) { restoreStateOfTarget(fn[bookkeeping]); } } +function _inherits(subClass, superClass) { + if ("function" !== typeof superClass && null !== superClass) + throw new TypeError( + "Super expression must either be null or a function, not " + + typeof superClass + ); + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: !1, + writable: !0, + configurable: !0 + } + }); + superClass && + (Object.setPrototypeOf + ? Object.setPrototypeOf(subClass, superClass) + : (subClass.__proto__ = superClass)); +} +(function(_React$Component) { + function ReactNativeComponent() { + if (!(this instanceof ReactNativeComponent)) + throw new TypeError("Cannot call a class as a function"); + var call = _React$Component.apply(this, arguments); + if (!this) + throw new ReferenceError( + "this hasn't been initialised - super() hasn't been called" + ); + return !call || ("object" !== typeof call && "function" !== typeof call) + ? this + : call; + } + _inherits(ReactNativeComponent, _React$Component); + ReactNativeComponent.prototype.blur = function() {}; + ReactNativeComponent.prototype.focus = function() {}; + ReactNativeComponent.prototype.measure = function() {}; + ReactNativeComponent.prototype.measureInWindow = function() {}; + ReactNativeComponent.prototype.measureLayout = function() {}; + ReactNativeComponent.prototype.setNativeProps = function() {}; + return ReactNativeComponent; +})(React.Component); +new Map(); +new Map(); +new Set(); +new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { batchedUpdates(function() { var events = nativeEvent.target; @@ -1466,7 +1548,9 @@ function dispatchEvent(target, topLevelType, nativeEvent) { forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); if (eventQueue) throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); if (hasRethrowError) throw ((events = rethrowError), @@ -1478,24 +1562,26 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } function shim$1() { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, +var _nativeFabricUIManage$1 = nativeFabricUIManager, + createNode = _nativeFabricUIManage$1.createNode, + cloneNode = _nativeFabricUIManage$1.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage$1.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, + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage$1.createChildSet, + appendChildNode = _nativeFabricUIManage$1.appendChild, + appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, + completeRoot = _nativeFabricUIManage$1.completeRoot, + registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, + fabricMeasure = _nativeFabricUIManage$1.measure, + fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1557,7 +1643,7 @@ function createTextInstance( ) { if (!hostContext.isInAParentText) throw ReactError( - "Text strings must be rendered within a component." + Error("Text strings must be rendered within a component.") ); hostContext = nextReactTag; nextReactTag += 2; @@ -1672,7 +1758,9 @@ function popTopLevelContextObject(fiber) { function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); @@ -1685,10 +1773,12 @@ function processChildContext(fiber, type, parentContext) { for (var contextKey in instance) if (!(contextKey in fiber)) throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); return Object.assign({}, parentContext, instance); } @@ -1710,7 +1800,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { var instance = workInProgress.stateNode; if (!instance) throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); didChange ? ((type = processChildContext(workInProgress, type, previousContext)), @@ -1721,40 +1813,11 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -var onCommitFiberRoot = null, - onCommitFiberUnmount = null; -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) {} - }; -} -var isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; -function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - var rendererID = hook.inject(internals); - onCommitFiberRoot = catchErrors(function(root) { - hook.onCommitFiberRoot( - rendererID, - root, - void 0, - 64 === (root.current.effectTag & 64) - ); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) {} - return !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 = Scheduler.unstable_now, Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel, @@ -1768,12 +1831,16 @@ if ( null == tracing.__interactionsRef.current ) throw ReactError( - "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 http://fb.me/react-profiling" + 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 http://fb.me/react-profiling" + ) ); var fakeCallbackNode = {}, - immediateQueue = null, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, immediateQueueCallbackNode = null, - isFlushingImmediate = !1, + isFlushingSyncQueue = !1, initialTimeMs = Scheduler_now(), now = 1e4 > initialTimeMs @@ -1794,7 +1861,7 @@ function getCurrentPriorityLevel() { case Scheduler_IdlePriority: return 95; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function reactPriorityToSchedulerPriority(reactPriorityLevel) { @@ -1810,54 +1877,55 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case 95: return Scheduler_IdlePriority; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (99 === reactPriorityLevel) - return ( - null === immediateQueue - ? ((immediateQueue = [callback]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ))) - : immediateQueue.push(callback), - fakeCallbackNode - ); reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function flushImmediateQueue() { +function scheduleSyncCallback(callback) { + null === syncQueue + ? ((syncQueue = [callback]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(callback); + return fakeCallbackNode; +} +function flushSyncCallbackQueue() { null !== immediateQueueCallbackNode && Scheduler_cancelCallback(immediateQueueCallbackNode); - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && null !== immediateQueue) { - isFlushingImmediate = !0; +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; var i = 0; try { - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do callback = callback(!0); - while (null !== callback); - } - immediateQueue = null; + var queue = syncQueue; + runWithPriority$1(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; } catch (error) { - throw (null !== immediateQueue && - (immediateQueue = immediateQueue.slice(i + 1)), + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ), error); } finally { - isFlushingImmediate = !1; + isFlushingSyncQueue = !1; } } } @@ -1865,7 +1933,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (1073741823 === expirationTime) return 99; if (1 === expirationTime) return 95; currentTime = - 10 * (1073741822 - expirationTime) - 10 * (1073741822 - currentTime); + 10 * (1073741821 - expirationTime) - 10 * (1073741821 - currentTime); return 0 >= currentTime ? 99 : 250 >= currentTime @@ -1947,7 +2015,7 @@ var valueCursor = { current: null }, currentlyRenderingFiber = null, lastContextDependency = null, lastContextWithAllBitsObserved = null; -function resetContextDependences() { +function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } function pushProvider(providerFiber, nextValue) { @@ -1960,14 +2028,32 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); providerFiber.type._context._currentValue2 = currentValue; } +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + for (; null !== parent; ) { + var alternate = parent.alternate; + if (parent.childExpirationTime < renderExpirationTime) + (parent.childExpirationTime = renderExpirationTime), + null !== alternate && + alternate.childExpirationTime < renderExpirationTime && + (alternate.childExpirationTime = renderExpirationTime); + else if ( + null !== alternate && + alternate.childExpirationTime < renderExpirationTime + ) + alternate.childExpirationTime = renderExpirationTime; + else break; + parent = parent.return; + } +} function prepareToReadContext(workInProgress, renderExpirationTime) { currentlyRenderingFiber = workInProgress; lastContextWithAllBitsObserved = lastContextDependency = null; - var currentDependencies = workInProgress.contextDependencies; - null !== currentDependencies && - currentDependencies.expirationTime >= renderExpirationTime && - (didReceiveUpdate = !0); - workInProgress.contextDependencies = null; + workInProgress = workInProgress.dependencies; + null !== workInProgress && + null !== workInProgress.firstContext && + (workInProgress.expirationTime >= renderExpirationTime && + (didReceiveUpdate = !0), + (workInProgress.firstContext = null)); } function readContext(context, observedBits) { if ( @@ -1981,12 +2067,16 @@ function readContext(context, observedBits) { if (null === lastContextDependency) { if (null === currentlyRenderingFiber) throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); lastContextDependency = observedBits; - currentlyRenderingFiber.contextDependencies = { - first: observedBits, - expirationTime: 0 + currentlyRenderingFiber.dependencies = { + expirationTime: 0, + firstContext: observedBits, + listeners: null, + responders: null }; } else lastContextDependency = lastContextDependency.next = observedBits; } @@ -2019,9 +2109,10 @@ function cloneUpdateQueue(currentQueue) { lastCapturedEffect: null }; } -function createUpdate(expirationTime) { +function createUpdate(expirationTime, suspenseConfig) { return { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, @@ -2137,8 +2228,10 @@ function processUpdateQueue( ((newFirstUpdate = update), (newBaseState = resultState)), newExpirationTime < updateExpirationTime && (newExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), (resultState = getStateFromUpdate( workInProgress, queue, @@ -2214,15 +2307,18 @@ function commitUpdateEffects(effect, instance) { var context = instance; if ("function" !== typeof _callback3) throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - _callback3 + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + _callback3 + ) ); _callback3.call(context); } effect = effect.nextEffect; } } -var emptyRefsObject = new React.Component().refs; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + emptyRefsObject = new React.Component().refs; function applyDerivedStateFromProps( workInProgress, ctor, @@ -2249,36 +2345,42 @@ var classComponentUpdater = { }, enqueueSetState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 1; + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 2; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 2; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); } }; @@ -2407,15 +2509,19 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); inst = element.stateNode; } if (!inst) throw ReactError( - "Missing owner for string ref " + - returnFiber + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + returnFiber + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); var stringRef = "" + returnFiber; if ( @@ -2435,13 +2541,17 @@ function coerceRef(returnFiber, current$$1, element) { } if ("string" !== typeof returnFiber) throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); if (!element._owner) throw ReactError( - "Element ref was specified as a string (" + - returnFiber + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + returnFiber + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } return returnFiber; @@ -2449,11 +2559,13 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) throw ReactError( - "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === Object.prototype.toString.call(newChild) + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + ) ); } function ChildReconciler(shouldTrackSideEffects) { @@ -2856,11 +2968,13 @@ function ChildReconciler(shouldTrackSideEffects) { var iteratorFn = getIteratorFn(newChildrenIterable); if ("function" !== typeof iteratorFn) throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); newChildrenIterable = iteratorFn.call(newChildrenIterable); if (null == newChildrenIterable) - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); for ( var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, @@ -3095,8 +3209,10 @@ function ChildReconciler(shouldTrackSideEffects) { case 0: throw ((returnFiber = returnFiber.type), ReactError( - (returnFiber.displayName || returnFiber.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (returnFiber.displayName || returnFiber.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) )); } return deleteRemainingChildren(returnFiber, currentFirstChild); @@ -3111,7 +3227,9 @@ var reconcileChildFibers = ChildReconciler(!0), function requiredContext(c) { if (c === NO_CONTEXT) throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); return c; } @@ -3149,6 +3267,50 @@ function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } +var SubtreeSuspenseContextMask = 1, + InvisibleParentSuspenseContext = 1, + ForceSuspenseFallback = 2, + suspenseStackCursor = { current: 0 }; +function findFirstSuspended(row) { + for (var node = row; null !== node; ) { + if (13 === node.tag) { + if (null !== node.memoizedState) return node; + } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { + if (0 !== (node.effectTag & 64)) return node; + } else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; +} +var currentListenerHookIndex = 0; +function updateListenerHook(responder, props) { + var dependencies = null.dependencies; + null === dependencies && + (dependencies = null.dependencies = { + expirationTime: 0, + firstContext: null, + listeners: [], + responders: null + }); + var listeners = dependencies.listeners; + null === listeners && (dependencies.listeners = listeners = []); + listeners.length === currentListenerHookIndex + ? (listeners.push({ responder: responder, props: props }), + currentListenerHookIndex++) + : ((listeners = listeners[currentListenerHookIndex++]), + (listeners.responder = responder), + (listeners.props = props)); +} var NoEffect$1 = 0, UnmountSnapshot = 2, UnmountMutation = 4, @@ -3173,7 +3335,9 @@ var NoEffect$1 = 0, numberOfReRenders = 0; function throwInvalidHookError() { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } function areHookInputsEqual(nextDeps, prevDeps) { @@ -3223,7 +3387,9 @@ function renderWithHooks( sideEffectTag = 0; if (current) throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); return workInProgress; } @@ -3259,7 +3425,9 @@ function updateWorkInProgressHook() { (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) - throw ReactError("Rendered more hooks than during the previous render."); + throw ReactError( + Error("Rendered more hooks than during the previous render.") + ); currentHook = nextCurrentHook; var newHook = { memoizedState: currentHook.memoizedState, @@ -3284,7 +3452,9 @@ function updateReducer(reducer) { queue = hook.queue; if (null === queue) throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); queue.lastRenderedReducer = reducer; if (0 < numberOfReRenders) { @@ -3327,8 +3497,10 @@ function updateReducer(reducer) { (firstRenderPhaseUpdate = newState)), updateExpirationTime > remainingExpirationTime && (remainingExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ), (newState = _update.eagerReducer === reducer ? _update.eagerState @@ -3407,7 +3579,9 @@ function mountDebugValue() {} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); var alternate = fiber.alternate; if ( @@ -3418,6 +3592,7 @@ function dispatchAction(fiber, queue, action) { ((didScheduleRenderPhaseUpdate = !0), (fiber = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, @@ -3433,24 +3608,29 @@ function dispatchAction(fiber, queue, action) { queue.next = fiber; } else { - flushPassiveEffects(); - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, fiber); - var _update2 = { - expirationTime: currentTime, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }, - _last = queue.last; - if (null === _last) _update2.next = _update2; + var currentTime = requestCurrentTime(), + _suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); + _suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: _suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var _last = queue.last; + if (null === _last) _suspenseConfig.next = _suspenseConfig; else { var first = _last.next; - null !== first && (_update2.next = first); - _last.next = _update2; + null !== first && (_suspenseConfig.next = first); + _last.next = _suspenseConfig; } - queue.last = _update2; + queue.last = _suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3459,8 +3639,8 @@ function dispatchAction(fiber, queue, action) { try { var currentState = queue.lastRenderedState, _eagerState = alternate(currentState, action); - _update2.eagerReducer = alternate; - _update2.eagerState = _eagerState; + _suspenseConfig.eagerReducer = alternate; + _suspenseConfig.eagerState = _eagerState; if (is(_eagerState, currentState)) return; } catch (error) { } finally { @@ -3479,7 +3659,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3552,7 +3733,8 @@ var ContextOnlyDispatcher = { ); return [hook.memoizedState, initialState]; }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, HooksDispatcherOnUpdate = { readContext: readContext, @@ -3606,7 +3788,8 @@ var ContextOnlyDispatcher = { useState: function(initialState) { return updateReducer(basicStateReducer, initialState); }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -4162,6 +4345,7 @@ function pushHostRootContext(workInProgress) { pushTopLevelContextObject(workInProgress, root.context, !1); pushHostContainer(workInProgress, root.containerInfo); } +var SUSPENDED_MARKER = {}; function updateSuspenseComponent( current$$1, workInProgress, @@ -4169,35 +4353,50 @@ function updateSuspenseComponent( ) { var mode = workInProgress.mode, nextProps = workInProgress.pendingProps, - nextState = workInProgress.memoizedState; - if (0 === (workInProgress.effectTag & 64)) { - nextState = null; - var nextDidTimeout = !1; - } else - (nextState = { - fallbackExpirationTime: - null !== nextState ? nextState.fallbackExpirationTime : 0 - }), + suspenseContext = suspenseStackCursor.current, + nextState = null, + nextDidTimeout = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || + (JSCompiler_temp = + 0 !== (suspenseContext & ForceSuspenseFallback) && + (null === current$$1 || null !== current$$1.memoizedState)); + JSCompiler_temp + ? ((nextState = SUSPENDED_MARKER), (nextDidTimeout = !0), - (workInProgress.effectTag &= -65); + (workInProgress.effectTag &= -65)) + : (null !== current$$1 && null === current$$1.memoizedState) || + void 0 === nextProps.fallback || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= InvisibleParentSuspenseContext); + suspenseContext &= SubtreeSuspenseContextMask; + push(suspenseStackCursor, suspenseContext, workInProgress); if (null === current$$1) if (nextDidTimeout) { - var nextFallbackChildren = nextProps.fallback; + nextProps = nextProps.fallback; current$$1 = createFiberFromFragment(null, mode, 0, null); - 0 === (workInProgress.mode & 1) && - (current$$1.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child); + current$$1.return = workInProgress; + if (0 === (workInProgress.mode & 2)) + for ( + nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + current$$1.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = current$$1), + (nextDidTimeout = nextDidTimeout.sibling); renderExpirationTime = createFiberFromFragment( - nextFallbackChildren, + nextProps, mode, renderExpirationTime, null ); + renderExpirationTime.return = workInProgress; current$$1.sibling = renderExpirationTime; mode = current$$1; - mode.return = renderExpirationTime.return = workInProgress; } else mode = renderExpirationTime = mountChildFibers( workInProgress, @@ -4208,95 +4407,235 @@ function updateSuspenseComponent( else { if (null !== current$$1.memoizedState) if ( - ((nextFallbackChildren = current$$1.child), - (mode = nextFallbackChildren.sibling), + ((suspenseContext = current$$1.child), + (mode = suspenseContext.sibling), nextDidTimeout) ) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - nextFallbackChildren, - nextFallbackChildren.pendingProps, + suspenseContext, + suspenseContext.pendingProps, 0 ); - 0 === (workInProgress.mode & 1) && + renderExpirationTime.return = workInProgress; + if ( + 0 === (workInProgress.mode & 2) && ((nextDidTimeout = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== nextFallbackChildren.child && - (renderExpirationTime.child = nextDidTimeout)); - if (workInProgress.mode & 4) { - nextFallbackChildren = 0; + nextDidTimeout !== suspenseContext.child) + ) for ( - nextDidTimeout = renderExpirationTime.child; + renderExpirationTime.child = nextDidTimeout; null !== nextDidTimeout; ) - (nextFallbackChildren += nextDidTimeout.treeBaseDuration), + (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - renderExpirationTime.treeBaseDuration = nextFallbackChildren; + if (workInProgress.mode & 8) { + nextDidTimeout = 0; + for ( + suspenseContext = renderExpirationTime.child; + null !== suspenseContext; + + ) + (nextDidTimeout += suspenseContext.treeBaseDuration), + (suspenseContext = suspenseContext.sibling); + renderExpirationTime.treeBaseDuration = nextDidTimeout; } - nextFallbackChildren = renderExpirationTime.sibling = createWorkInProgress( - mode, - nextProps, - mode.expirationTime - ); + nextProps = createWorkInProgress(mode, nextProps, mode.expirationTime); + nextProps.return = workInProgress; + renderExpirationTime.sibling = nextProps; mode = renderExpirationTime; renderExpirationTime.childExpirationTime = 0; - renderExpirationTime = nextFallbackChildren; - mode.return = renderExpirationTime.return = workInProgress; + renderExpirationTime = nextProps; } else mode = renderExpirationTime = reconcileChildFibers( workInProgress, - nextFallbackChildren.child, + suspenseContext.child, nextProps.children, renderExpirationTime ); - else { - var _currentPrimaryChild = current$$1.child; - if (nextDidTimeout) { - nextProps = nextProps.fallback; - nextFallbackChildren = createFiberFromFragment(null, mode, 0, null); - nextFallbackChildren.child = _currentPrimaryChild; - 0 === (workInProgress.mode & 1) && - (nextFallbackChildren.child = + else if (((suspenseContext = current$$1.child), nextDidTimeout)) { + nextDidTimeout = nextProps.fallback; + nextProps = createFiberFromFragment(null, mode, 0, null); + nextProps.return = workInProgress; + nextProps.child = suspenseContext; + null !== suspenseContext && (suspenseContext.return = nextProps); + if (0 === (workInProgress.mode & 2)) + for ( + suspenseContext = null !== workInProgress.memoizedState ? workInProgress.child.child - : workInProgress.child); - if (workInProgress.mode & 4) { - nextDidTimeout = 0; - for ( - _currentPrimaryChild = nextFallbackChildren.child; - null !== _currentPrimaryChild; + : workInProgress.child, + nextProps.child = suspenseContext; + null !== suspenseContext; + ) + (suspenseContext.return = nextProps), + (suspenseContext = suspenseContext.sibling); + if (workInProgress.mode & 8) { + suspenseContext = 0; + for (JSCompiler_temp = nextProps.child; null !== JSCompiler_temp; ) + (suspenseContext += JSCompiler_temp.treeBaseDuration), + (JSCompiler_temp = JSCompiler_temp.sibling); + nextProps.treeBaseDuration = suspenseContext; + } + renderExpirationTime = createFiberFromFragment( + nextDidTimeout, + mode, + renderExpirationTime, + null + ); + renderExpirationTime.return = workInProgress; + nextProps.sibling = renderExpirationTime; + renderExpirationTime.effectTag |= 2; + mode = nextProps; + nextProps.childExpirationTime = 0; + } else + renderExpirationTime = mode = reconcileChildFibers( + workInProgress, + suspenseContext, + nextProps.children, + renderExpirationTime + ); + workInProgress.stateNode = current$$1.stateNode; + } + workInProgress.memoizedState = nextState; + workInProgress.child = mode; + return renderExpirationTime; +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailExpiration = 0), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren( + current$$1, + workInProgress, + nextProps.children, + renderExpirationTime + ); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & ForceSuspenseFallback)) + (nextProps = + (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), + (workInProgress.effectTag |= 64); + else { + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) { + if (null !== current$$1.memoizedState) { + current$$1.expirationTime < renderExpirationTime && + (current$$1.expirationTime = renderExpirationTime); + var alternate = current$$1.alternate; + null !== alternate && + alternate.expirationTime < renderExpirationTime && + (alternate.expirationTime = renderExpirationTime); + scheduleWorkOnParentPath(current$$1.return, renderExpirationTime); + } + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress ) - (nextDidTimeout += _currentPrimaryChild.treeBaseDuration), - (_currentPrimaryChild = _currentPrimaryChild.sibling); - nextFallbackChildren.treeBaseDuration = nextDidTimeout; + break a; + current$$1 = current$$1.return; } - renderExpirationTime = nextFallbackChildren.sibling = createFiberFromFragment( - nextProps, - mode, + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + nextProps &= SubtreeSuspenseContextMask; + } + push(suspenseStackCursor, nextProps, workInProgress); + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderExpirationTime = workInProgress.child; + for (revealOrder = null; null !== renderExpirationTime; ) + (nextProps = renderExpirationTime.alternate), + null !== nextProps && + null === findFirstSuspended(nextProps) && + (revealOrder = renderExpirationTime), + (renderExpirationTime = renderExpirationTime.sibling); + renderExpirationTime = revealOrder; + null === renderExpirationTime + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderExpirationTime.sibling), + (renderExpirationTime.sibling = null)); + initSuspenseListRenderState( + workInProgress, + !1, + revealOrder, renderExpirationTime, - null + tailMode ); - renderExpirationTime.effectTag |= 2; - mode = nextFallbackChildren; - nextFallbackChildren.childExpirationTime = 0; - mode.return = renderExpirationTime.return = workInProgress; - } else - renderExpirationTime = mode = reconcileChildFibers( + break; + case "backwards": + renderExpirationTime = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + nextProps = revealOrder.alternate; + if (null !== nextProps && null === findFirstSuspended(nextProps)) { + workInProgress.child = revealOrder; + break; + } + nextProps = revealOrder.sibling; + revealOrder.sibling = renderExpirationTime; + renderExpirationTime = revealOrder; + revealOrder = nextProps; + } + initSuspenseListRenderState( workInProgress, - _currentPrimaryChild, - nextProps.children, - renderExpirationTime + !0, + renderExpirationTime, + null, + tailMode ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; } - workInProgress.stateNode = current$$1.stateNode; - } - workInProgress.memoizedState = nextState; - workInProgress.child = mode; - return renderExpirationTime; + return workInProgress.child; } function bailoutOnAlreadyFinishedWork( current$$1, @@ -4304,11 +4643,11 @@ function bailoutOnAlreadyFinishedWork( renderExpirationTime ) { null !== current$$1 && - (workInProgress.contextDependencies = current$$1.contextDependencies); + (workInProgress.dependencies = current$$1.dependencies); profilerStartTime = -1; if (workInProgress.childExpirationTime < renderExpirationTime) return null; if (null !== current$$1 && workInProgress.child !== current$$1.child) - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); if (null !== workInProgress.child) { current$$1 = workInProgress.child; renderExpirationTime = createWorkInProgress( @@ -4519,6 +4858,30 @@ updateHostText$1 = function(current, workInProgress, oldText, newText) { )), (workInProgress.effectTag |= 4)); }; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var _lastTailNode = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === _lastTailNode + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (_lastTailNode.sibling = null); + } +} function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4545,15 +4908,17 @@ function completeWork(current, workInProgress, renderExpirationTime) { break; case 5: popHostContext(workInProgress); - renderExpirationTime = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - type, + renderExpirationTime, newProps, - renderExpirationTime + rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); @@ -4561,33 +4926,35 @@ function completeWork(current, workInProgress, renderExpirationTime) { requiredContext(contextStackCursor$1.current); current = nextReactTag; nextReactTag += 2; - type = getViewConfigForType(type); + renderExpirationTime = getViewConfigForType(renderExpirationTime); var updatePayload = diffProperties( null, emptyObject, newProps, - type.validAttributes + renderExpirationTime.validAttributes ); - renderExpirationTime = createNode( + rootContainerInstance = createNode( current, - type.uiViewClassName, - renderExpirationTime, + renderExpirationTime.uiViewClassName, + rootContainerInstance, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - type, + renderExpirationTime, newProps, workInProgress ); - current = { node: renderExpirationTime, canonical: current }; + current = { node: rootContainerInstance, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; null !== workInProgress.ref && (workInProgress.effectTag |= 128); } else if (null === workInProgress.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -4601,14 +4968,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { else { if ("string" !== typeof newProps && null === workInProgress.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); current = requiredContext(rootInstanceStackCursor.current); - renderExpirationTime = requiredContext(contextStackCursor$1.current); + rootContainerInstance = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - renderExpirationTime, + rootContainerInstance, workInProgress ); } @@ -4616,35 +4985,41 @@ function completeWork(current, workInProgress, renderExpirationTime) { case 11: break; case 13: + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( (workInProgress.expirationTime = renderExpirationTime), workInProgress ); newProps = null !== newProps; - renderExpirationTime = !1; + rootContainerInstance = !1; null !== current && - ((type = current.memoizedState), - (renderExpirationTime = null !== type), + ((renderExpirationTime = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime), newProps || - null === type || - ((type = type.fallbackExpirationTime), - type < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = type), - (current = current.child.sibling), - null !== current && - ((type = workInProgress.firstEffect), - null !== type - ? ((workInProgress.firstEffect = current), - (current.nextEffect = type)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = current), - (current.nextEffect = null)), - (current.effectTag = 8)))); - newProps && - !renderExpirationTime && - 0 !== (workInProgress.mode & 1) && - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); + null === renderExpirationTime || + ((renderExpirationTime = current.child.sibling), + null !== renderExpirationTime && + ((updatePayload = workInProgress.firstEffect), + null !== updatePayload + ? ((workInProgress.firstEffect = renderExpirationTime), + (renderExpirationTime.nextEffect = updatePayload)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), + (renderExpirationTime.nextEffect = null)), + (renderExpirationTime.effectTag = 8)))); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & InvisibleParentSuspenseContext) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; newProps && (workInProgress.effectTag |= 4); break; case 7: @@ -4670,16 +5045,196 @@ function completeWork(current, workInProgress, renderExpirationTime) { case 18: break; case 19: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (null === newProps) break; + rootContainerInstance = 0 !== (workInProgress.effectTag & 64); + updatePayload = newProps.rendering; + if (null === updatePayload) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + workInProgress.firstEffect = workInProgress.lastEffect = null; + current = renderExpirationTime; + for (newProps = workInProgress.child; null !== newProps; ) + (rootContainerInstance = newProps), + (updatePayload = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (renderExpirationTime = rootContainerInstance.alternate), + null === renderExpirationTime + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = updatePayload), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null), + (rootContainerInstance.selfBaseDuration = 0), + (rootContainerInstance.treeBaseDuration = 0)) + : ((rootContainerInstance.childExpirationTime = + renderExpirationTime.childExpirationTime), + (rootContainerInstance.expirationTime = + renderExpirationTime.expirationTime), + (rootContainerInstance.child = + renderExpirationTime.child), + (rootContainerInstance.memoizedProps = + renderExpirationTime.memoizedProps), + (rootContainerInstance.memoizedState = + renderExpirationTime.memoizedState), + (rootContainerInstance.updateQueue = + renderExpirationTime.updateQueue), + (updatePayload = renderExpirationTime.dependencies), + (rootContainerInstance.dependencies = + null === updatePayload + ? null + : { + expirationTime: updatePayload.expirationTime, + firstContext: updatePayload.firstContext, + listeners: updatePayload.listeners, + responders: updatePayload.responders + }), + (rootContainerInstance.selfBaseDuration = + renderExpirationTime.selfBaseDuration), + (rootContainerInstance.treeBaseDuration = + renderExpirationTime.treeBaseDuration)), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & SubtreeSuspenseContextMask) | + ForceSuspenseFallback, + workInProgress + ); + return workInProgress.child; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && "hidden" === newProps.tailMode) + ) { + current = current.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + workInProgress = workInProgress.lastEffect = newProps.lastEffect; + null !== workInProgress && (workInProgress.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime && + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (current = renderExpirationTime - 1), + (workInProgress.expirationTime = workInProgress.childExpirationTime = current), + null === spawnedWorkDuringRender + ? (spawnedWorkDuringRender = [current]) + : spawnedWorkDuringRender.push(current)); + newProps.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = newProps.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (newProps.last = updatePayload)); + } + if (null !== newProps.tail) + return ( + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500), + (current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (current.sibling = null), + (newProps = suspenseStackCursor.current), + (newProps = rootContainerInstance + ? (newProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback + : newProps & SubtreeSuspenseContextMask), + push(suspenseStackCursor, newProps, workInProgress), + current + ); break; case 20: break; default: throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } return null; } +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + workInProgress.effectTag = (effectTag & -2049) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null + ); + case 18: + return null; + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} function createCapturedValue(value, source) { return { value: value, @@ -4687,24 +5242,18 @@ function createCapturedValue(value, source) { stack: getStackByFiberInDevAndProd(source) }; } +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") + ); function logCapturedError(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - if (error instanceof Error) { - capturedError = error.message; - var name = error.name; - try { - error.message = - (capturedError ? name + ": " + capturedError : name) + - "\n\nThis error is located at:" + - componentStack; - } catch (e) {} - } else - error = - "string" === typeof error - ? Error(error + "\n\nThis error is located at:" + componentStack) - : Error("Unspecified error at:" + componentStack); - ReactNativePrivateInterface.ExceptionsManager.handleException(error, !1); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ) && console.error(capturedError.error); } var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; function logError(boundary, errorInfo) { @@ -4775,7 +5324,12 @@ function commitWork(current$$1, finishedWork) { case 12: return; case 13: - commitSuspenseComponent(finishedWork); + null !== finishedWork.memoizedState && + (globalMostRecentFallbackTime = now()); + attachSuspenseRetryListeners(finishedWork); + return; + case 19: + attachSuspenseRetryListeners(finishedWork); return; } switch (finishedWork.tag) { @@ -4783,29 +5337,26 @@ function commitWork(current$$1, finishedWork) { case 5: case 6: case 20: - case 19: break; case 3: case 4: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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 commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; - null !== newState && - 0 === newState.fallbackExpirationTime && - (newState.fallbackExpirationTime = requestCurrentTime() - 500); - newState = finishedWork.updateQueue; - if (null !== newState) { +function attachSuspenseRetryListeners(finishedWork) { + var thenables = finishedWork.updateQueue; + if (null !== thenables) { finishedWork.updateQueue = null; var retryCache = finishedWork.stateNode; null === retryCache && (retryCache = finishedWork.stateNode = new PossiblyWeakSet$1()); - newState.forEach(function(thenable) { + thenables.forEach(function(thenable) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); retryCache.has(thenable) || ((retry = tracing.unstable_wrap(retry)), @@ -4816,7 +5367,7 @@ function commitSuspenseComponent(finishedWork) { } var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; expirationTime.payload = { element: null }; var error = errorInfo.value; @@ -4827,7 +5378,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { @@ -4853,64 +5404,29 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { }); return expirationTime; } -function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null; - case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -2049) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: - return ( - (effectTag = workInProgress.effectTag), - effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null - ); - case 18: - return null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 19: - case 20: - return null; - default: - return null; - } -} var ceil = Math.ceil, ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - LegacyUnbatchedPhase = 2, - RenderPhase = 4, - CommitPhase = 5, + NoContext = 0, + LegacyUnbatchedContext = 8, + RenderContext = 16, + CommitContext = 32, RootIncomplete = 0, RootErrored = 1, RootSuspended = 2, - RootCompleted = 3, - workPhase = 0, + RootSuspendedWithDelay = 3, + RootCompleted = 4, + executionContext = NoContext, workInProgressRoot = null, workInProgress = null, renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, - workInProgressRootMostRecentEventTime = 1073741823, + workInProgressRootLatestProcessedExpirationTime = 1073741823, + workInProgressRootLatestSuspenseTimeout = 1073741823, + workInProgressRootCanSuspendUsingConfig = null, + workInProgressRootHasPendingPing = !1, + globalMostRecentFallbackTime = 0, + FALLBACK_THROTTLE_MS = 500, nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, @@ -4921,36 +5437,52 @@ var ceil = Math.ceil, rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, + spawnedWorkDuringRender = null, currentEventTime = 0; function requestCurrentTime() { - return workPhase === RenderPhase || workPhase === CommitPhase - ? 1073741822 - ((now() / 10) | 0) + return (executionContext & (RenderContext | CommitContext)) !== NoContext + ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime ? currentEventTime - : (currentEventTime = 1073741822 - ((now() / 10) | 0)); -} -function computeExpirationForFiber(currentTime, fiber) { - if (0 === (fiber.mode & 1)) return 1073741823; - if (workPhase === RenderPhase) return renderExpirationTime; - switch (getCurrentPriorityLevel()) { - case 99: - currentTime = 1073741823; - break; - case 98: - currentTime = - 1073741822 - 10 * ((((1073741822 - currentTime + 15) / 10) | 0) + 1); - break; - case 97: - case 96: - currentTime = - 1073741822 - 25 * ((((1073741822 - currentTime + 500) / 25) | 0) + 1); - break; - case 95: - currentTime = 1; - break; - default: - throw ReactError("Expected a valid priority level"); - } + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); +} +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + fiber = fiber.mode; + if (0 === (fiber & 2)) return 1073741823; + var priorityLevel = getCurrentPriorityLevel(); + if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; + if ((executionContext & RenderContext) !== NoContext) + return renderExpirationTime; + if (null !== suspenseConfig) + currentTime = + 1073741821 - + 25 * + ((((1073741821 - + currentTime + + (suspenseConfig.timeoutMs | 0 || 5e3) / 10) / + 25) | + 0) + + 1); + else + switch (priorityLevel) { + case 99: + currentTime = 1073741823; + break; + case 98: + currentTime = + 1073741821 - 10 * ((((1073741821 - currentTime + 15) / 10) | 0) + 1); + break; + case 97: + case 96: + currentTime = + 1073741821 - 25 * ((((1073741821 - currentTime + 500) / 25) | 0) + 1); + break; + case 95: + currentTime = 1; + break; + default: + throw ReactError(Error("Expected a valid priority level")); + } null !== workInProgressRoot && currentTime === renderExpirationTime && --currentTime; @@ -4961,33 +5493,42 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) )); fiber = markUpdateTimeFromFiberToRoot(fiber, expirationTime); - if (null !== fiber) - if (((fiber.pingTime = 0), 1073741823 === expirationTime)) - if (workPhase === LegacyUnbatchedPhase) + if (null !== fiber) { + fiber.pingTime = 0; + var priorityLevel = getCurrentPriorityLevel(); + if (1073741823 === expirationTime) + if ( + (executionContext & LegacyUnbatchedContext) !== NoContext && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + scheduleInteractions( + fiber, + expirationTime, + tracing.__interactionsRef.current + ); for ( - expirationTime = renderRoot(fiber, 1073741823, !0); - null !== expirationTime; + var callback = renderRoot(fiber, 1073741823, !0); + null !== callback; ) - expirationTime = expirationTime(!0); - else + callback = callback(!0); + } else scheduleCallbackForRoot(fiber, 99, 1073741823), - 0 === workPhase && flushImmediateQueue(); - else { - var priorityLevel = getCurrentPriorityLevel(); - if (98 === priorityLevel) - if (null === rootsWithPendingDiscreteUpdates) - rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]]); - else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(fiber); - (void 0 === lastDiscreteTime || lastDiscreteTime > expirationTime) && - rootsWithPendingDiscreteUpdates.set(fiber, expirationTime); - } - scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); - } + executionContext === NoContext && flushSyncCallbackQueue(); + else scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); + (executionContext & 4) === NoContext || + (98 !== priorityLevel && 99 !== priorityLevel) || + (null === rootsWithPendingDiscreteUpdates + ? (rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]])) + : ((priorityLevel = rootsWithPendingDiscreteUpdates.get(fiber)), + (void 0 === priorityLevel || priorityLevel > expirationTime) && + rootsWithPendingDiscreteUpdates.set(fiber, expirationTime))); + } } function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { fiber.expirationTime < expirationTime && @@ -5028,23 +5569,30 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode); root.callbackExpirationTime = expirationTime; - existingCallbackNode = null; - 1073741823 !== expirationTime && - 1 !== expirationTime && - ((existingCallbackNode = 10 * (1073741822 - expirationTime) - now()), - 5e3 < existingCallbackNode && (existingCallbackNode = 5e3), - (existingCallbackNode = { timeout: existingCallbackNode })); - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - existingCallbackNode - ); + 1073741823 === expirationTime + ? (root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + )) + : ((existingCallbackNode = null), + 1 !== expirationTime && + (existingCallbackNode = { + timeout: 10 * (1073741821 - expirationTime) - now() + }), + (root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + existingCallbackNode + ))); } - schedulePendingInteraction(root, expirationTime); + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); } function runRootCallback(root, callback, isSync) { var prevCallbackNode = root.callbackNode, @@ -5067,9 +5615,7 @@ function resolveLocksOnRoot(root, expirationTime) { return null !== firstBatch && firstBatch._defer && firstBatch._expirationTime >= expirationTime - ? ((root.finishedWork = root.current.alternate), - (root.pendingCommitExpirationTime = expirationTime), - scheduleCallback(97, function() { + ? (scheduleCallback(97, function() { firstBatch._onComplete(); return null; }), @@ -5081,13 +5627,14 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback(99, renderRoot.bind(null, root, expirationTime)); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = 0; + root.finishedWork = null; + root.finishedExpirationTime = 0; var timeoutHandle = root.timeoutHandle; -1 !== timeoutHandle && ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); @@ -5111,6 +5658,12 @@ function prepareFreshStack(root, expirationTime) { case 4: popHostContainer(interruptedWork); break; + case 13: + pop(suspenseStackCursor, interruptedWork); + break; + case 19: + pop(suspenseStackCursor, interruptedWork); + break; case 10: popProvider(interruptedWork); } @@ -5120,27 +5673,35 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = 1073741823; + workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = !1; + spawnedWorkDuringRender = null; } function renderRoot(root$jscomp$0, expirationTime, isSync) { - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); if (root$jscomp$0.firstPendingTime < expirationTime) return null; - if (root$jscomp$0.pendingCommitExpirationTime === expirationTime) - return ( - (root$jscomp$0.pendingCommitExpirationTime = 0), - commitRoot.bind(null, root$jscomp$0, expirationTime) - ); + if (isSync && root$jscomp$0.finishedExpirationTime === expirationTime) + return commitRoot.bind(null, root$jscomp$0); flushPassiveEffects(); if ( root$jscomp$0 !== workInProgressRoot || expirationTime !== renderExpirationTime ) prepareFreshStack(root$jscomp$0, expirationTime), - startWorkOnPendingInteraction(root$jscomp$0, expirationTime); + startWorkOnPendingInteractions(root$jscomp$0, expirationTime); + else if (workInProgressRootExitStatus === RootSuspendedWithDelay) + if (workInProgressRootHasPendingPing) + prepareFreshStack(root$jscomp$0, expirationTime); + else { + var lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + } if (null !== workInProgress) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + lastPendingTime = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; null === prevDispatcher && (prevDispatcher = ContextOnlyDispatcher); ReactCurrentDispatcher.current = ContextOnlyDispatcher; @@ -5151,8 +5712,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) return ( - (workPhase = prevWorkPhase), - resetContextDependences(), + (executionContext = lastPendingTime), + resetContextDependencies(), (ReactCurrentDispatcher.current = prevDispatcher), (tracing.__interactionsRef.current = prevInteractions), renderRoot.bind(null, root$jscomp$0, currentTime) @@ -5169,14 +5730,14 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = performUnitOfWork(workInProgress); break; } catch (thrownValue) { - resetContextDependences(); + resetContextDependencies(); resetHooks(); currentTime = workInProgress; if (null === currentTime || null === currentTime.return) throw (prepareFreshStack(root$jscomp$0, expirationTime), - (workPhase = prevWorkPhase), + (executionContext = lastPendingTime), thrownValue); - currentTime.mode & 4 && + currentTime.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(currentTime, !0); a: { var root = root$jscomp$0, @@ -5191,29 +5752,41 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; + var thenable = value, + hasInvisibleParentBoundary = + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext); value = returnFiber; do { - if ( - 13 === value.tag && - (void 0 === value.memoizedProps.fallback - ? 0 - : null === value.memoizedState) - ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === value.tag)) + null !== value.memoizedState + ? (JSCompiler_temp = !1) + : ((JSCompiler_temp = value.memoizedProps), + (JSCompiler_temp = + void 0 === JSCompiler_temp.fallback + ? !1 + : !0 !== JSCompiler_temp.unstable_avoidThisFallback + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0)); + if (JSCompiler_temp) { returnFiber = value.updateQueue; null === returnFiber ? ((returnFiber = new Set()), returnFiber.add(thenable), (value.updateQueue = returnFiber)) : returnFiber.add(thenable); - if (0 === (value.mode & 1)) { + if (0 === (value.mode & 2)) { value.effectTag |= 64; sourceFiber.effectTag &= -1957; 1 === sourceFiber.tag && (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((renderExpirationTime$jscomp$0 = createUpdate( - 1073741823 + 1073741823, + null )), (renderExpirationTime$jscomp$0.tag = 2), enqueueUpdate( @@ -5225,15 +5798,15 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { } sourceFiber = root; root = renderExpirationTime$jscomp$0; - var pingCache = sourceFiber.pingCache; - null === pingCache - ? ((pingCache = sourceFiber.pingCache = new PossiblyWeakMap()), + hasInvisibleParentBoundary = sourceFiber.pingCache; + null === hasInvisibleParentBoundary + ? ((hasInvisibleParentBoundary = sourceFiber.pingCache = new PossiblyWeakMap()), (returnFiber = new Set()), - pingCache.set(thenable, returnFiber)) - : ((returnFiber = pingCache.get(thenable)), + hasInvisibleParentBoundary.set(thenable, returnFiber)) + : ((returnFiber = hasInvisibleParentBoundary.get(thenable)), void 0 === returnFiber && ((returnFiber = new Set()), - pingCache.set(thenable, returnFiber))); + hasInvisibleParentBoundary.set(thenable, returnFiber))); returnFiber.has(root) || (returnFiber.add(root), (sourceFiber = pingSuspendedRoot.bind( @@ -5256,11 +5829,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { getStackByFiberInDevAndProd(sourceFiber) ); } - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootErrored; + workInProgressRootExitStatus !== RootCompleted && + (workInProgressRootExitStatus = RootErrored); value = createCapturedValue(value, sourceFiber); sourceFiber = returnFiber; do { @@ -5312,80 +5882,148 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = completeUnitOfWork(currentTime); } while (1); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = lastPendingTime; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; tracing.__interactionsRef.current = prevInteractions; if (null !== workInProgress) return renderRoot.bind(null, root$jscomp$0, expirationTime); } + root$jscomp$0.finishedWork = root$jscomp$0.current.alternate; + root$jscomp$0.finishedExpirationTime = expirationTime; if (resolveLocksOnRoot(root$jscomp$0, expirationTime)) return null; workInProgressRoot = null; switch (workInProgressRootExitStatus) { case RootIncomplete: - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); case RootErrored: return ( - (prevWorkPhase = root$jscomp$0.lastPendingTime), - root$jscomp$0.lastPendingTime < expirationTime - ? renderRoot.bind(null, root$jscomp$0, prevWorkPhase) + (lastPendingTime = root$jscomp$0.lastPendingTime), + lastPendingTime < expirationTime + ? renderRoot.bind(null, root$jscomp$0, lastPendingTime) : isSync - ? commitRoot.bind(null, root$jscomp$0, expirationTime) + ? commitRoot.bind(null, root$jscomp$0) : (prepareFreshStack(root$jscomp$0, expirationTime), - scheduleCallback( - 99, + scheduleSyncCallback( renderRoot.bind(null, root$jscomp$0, expirationTime) ), null) ); case RootSuspended: + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + !isSync && + ((isSync = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < isSync) + ) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); + lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + isSync + ); + return null; + } + return commitRoot.bind(null, root$jscomp$0); + case RootSuspendedWithDelay: if (!isSync) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); isSync = root$jscomp$0.lastPendingTime; - if (root$jscomp$0.lastPendingTime < expirationTime) + if (isSync < expirationTime) return renderRoot.bind(null, root$jscomp$0, isSync); - if ( - 1073741823 !== workInProgressRootMostRecentEventTime && - ((prevWorkPhase = - 10 * (1073741822 - workInProgressRootMostRecentEventTime) - 5e3), - (isSync = now()), - (prevWorkPhase = isSync - prevWorkPhase), - (prevWorkPhase = - (120 > prevWorkPhase - ? 120 - : 480 > prevWorkPhase - ? 480 - : 1080 > prevWorkPhase - ? 1080 - : 1920 > prevWorkPhase - ? 1920 - : 3e3 > prevWorkPhase - ? 3e3 - : 4320 > prevWorkPhase - ? 4320 - : 1960 * ceil(prevWorkPhase / 1960)) - prevWorkPhase), - (isSync = 10 * (1073741822 - expirationTime) - isSync), - isSync < prevWorkPhase && (prevWorkPhase = isSync), - (isSync = prevWorkPhase), - 10 < isSync) - ) + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (isSync = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (isSync = 0) + : ((isSync = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (lastPendingTime = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - lastPendingTime), + (isSync = lastPendingTime - isSync), + 0 > isSync && (isSync = 0), + (isSync = + (120 > isSync + ? 120 + : 480 > isSync + ? 480 + : 1080 > isSync + ? 1080 + : 1920 > isSync + ? 1920 + : 3e3 > isSync + ? 3e3 + : 4320 > isSync + ? 4320 + : 1960 * ceil(isSync / 1960)) - isSync), + expirationTime < isSync && (isSync = expirationTime)); + if (10 < isSync) return ( (root$jscomp$0.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root$jscomp$0, expirationTime), + commitRoot.bind(null, root$jscomp$0), isSync )), null ); } - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return commitRoot.bind(null, root$jscomp$0); case RootCompleted: - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return !isSync && + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig && + ((lastPendingTime = workInProgressRootLatestProcessedExpirationTime), + (prevDispatcher = workInProgressRootCanSuspendUsingConfig), + (expirationTime = prevDispatcher.busyMinDurationMs | 0), + 0 >= expirationTime + ? (expirationTime = 0) + : ((isSync = prevDispatcher.busyDelayMs | 0), + (lastPendingTime = + now() - + (10 * (1073741821 - lastPendingTime) - + (prevDispatcher.timeoutMs | 0 || 5e3))), + (expirationTime = + lastPendingTime <= isSync + ? 0 + : isSync + expirationTime - lastPendingTime)), + 10 < expirationTime) + ? ((root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + expirationTime + )), + null) + : commitRoot.bind(null, root$jscomp$0); default: - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } } +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 1 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 1 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} function performUnitOfWork(unitOfWork) { var current$$1 = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 4) + 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), @@ -5402,7 +6040,7 @@ function completeUnitOfWork(unitOfWork) { var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 1024)) { - if (0 === (workInProgress.mode & 4)) + if (0 === (workInProgress.mode & 8)) current$$1 = completeWork( current$$1, workInProgress, @@ -5422,7 +6060,7 @@ function completeUnitOfWork(unitOfWork) { fiber = workInProgress; if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; - if (0 !== (fiber.mode & 4)) { + if (0 !== (fiber.mode & 8)) { for ( var actualDuration = fiber.actualDuration, treeBaseDuration = fiber.selfBaseDuration, @@ -5474,7 +6112,7 @@ function completeUnitOfWork(unitOfWork) { (unitOfWork.lastEffect = workInProgress))); } else { current$$1 = unwindWork(workInProgress, renderExpirationTime); - if (0 !== (workInProgress.mode & 4)) { + if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; for ( @@ -5500,8 +6138,8 @@ function completeUnitOfWork(unitOfWork) { (workInProgressRootExitStatus = RootCompleted); return null; } -function commitRoot(root, expirationTime) { - runWithPriority(99, commitRootImpl.bind(null, root, expirationTime)); +function commitRoot(root) { + runWithPriority$1(99, commitRootImpl.bind(null, root)); null !== rootWithPendingPassiveEffects && ((root = getCurrentPriorityLevel()), scheduleCallback(root, function() { @@ -5510,13 +6148,21 @@ function commitRoot(root, expirationTime) { })); return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); - var finishedWork = root.current.alternate; - if (null === finishedWork) - throw ReactError("Should have a work-in-progress root."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); + var finishedWork = root.finishedWork, + expirationTime = root.finishedExpirationTime; + if (null === finishedWork) return null; + root.finishedWork = null; + root.finishedExpirationTime = 0; + if (finishedWork === root.current) + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); root.callbackNode = null; root.callbackExpirationTime = 0; var updateExpirationTimeBeforeCommit = finishedWork.expirationTime, @@ -5530,19 +6176,19 @@ function commitRootImpl(root, expirationTime) { (root.lastPendingTime = updateExpirationTimeBeforeCommit); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); - if (1 < finishedWork.effectTag) - if (null !== finishedWork.lastEffect) { - finishedWork.lastEffect.nextEffect = finishedWork; - var firstEffect = finishedWork.firstEffect; - } else firstEffect = finishedWork; - else firstEffect = finishedWork.firstEffect; - if (null !== firstEffect) { - updateExpirationTimeBeforeCommit = workPhase; - workPhase = CommitPhase; - childExpirationTimeBeforeCommit = tracing.__interactionsRef.current; + 1 < finishedWork.effectTag + ? null !== finishedWork.lastEffect + ? ((finishedWork.lastEffect.nextEffect = finishedWork), + (updateExpirationTimeBeforeCommit = finishedWork.firstEffect)) + : (updateExpirationTimeBeforeCommit = finishedWork) + : (updateExpirationTimeBeforeCommit = finishedWork.firstEffect); + if (null !== updateExpirationTimeBeforeCommit) { + childExpirationTimeBeforeCommit = executionContext; + executionContext |= CommitContext; + var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; ReactCurrentOwner$2.current = null; - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5585,11 +6231,12 @@ function commitRootImpl(root, expirationTime) { case 6: case 4: case 17: - case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5597,13 +6244,13 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); commitTime = now$1(); - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5644,8 +6291,8 @@ function commitRootImpl(root, expirationTime) { if (null !== updateQueue) { var lastEffect = updateQueue.lastEffect; if (null !== lastEffect) { - var firstEffect$jscomp$0 = lastEffect.next; - snapshot = firstEffect$jscomp$0; + var firstEffect = lastEffect.next; + snapshot = firstEffect; do { var destroy = snapshot.destroy; if (void 0 !== destroy) { @@ -5660,7 +6307,7 @@ function commitRootImpl(root, expirationTime) { } } snapshot = snapshot.next; - } while (snapshot !== firstEffect$jscomp$0); + } while (snapshot !== firstEffect); } } break; @@ -5706,24 +6353,26 @@ function commitRootImpl(root, expirationTime) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; null !== alternate && ((alternate.return = null), (alternate.child = null), (alternate.memoizedState = null), - (alternate.updateQueue = null)); + (alternate.updateQueue = null), + (alternate.dependencies = null)); } nextEffect = nextEffect.nextEffect; } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); root.current = finishedWork; - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for ( @@ -5794,7 +6443,9 @@ function commitRootImpl(root, expirationTime) { case 5: if (null === current$$1$jscomp$1 && currentRef.effectTag & 4) throw ReactError( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -5803,26 +6454,27 @@ function commitRootImpl(root, expirationTime) { break; case 12: var onRender = currentRef.memoizedProps.onRender; - onRender( - currentRef.memoizedProps.id, - null === current$$1$jscomp$1 ? "mount" : "update", - currentRef.actualDuration, - currentRef.treeBaseDuration, - currentRef.actualStartTime, - commitTime, - lastEffect.memoizedInteractions - ); + "function" === typeof onRender && + onRender( + currentRef.memoizedProps.id, + null === current$$1$jscomp$1 ? "mount" : "update", + currentRef.actualDuration, + currentRef.treeBaseDuration, + currentRef.actualStartTime, + commitTime, + lastEffect.memoizedInteractions + ); break; case 13: + case 19: case 17: - break; case 20: break; - case 19: - break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5847,32 +6499,51 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); nextEffect = null; - tracing.__interactionsRef.current = childExpirationTimeBeforeCommit; - workPhase = updateExpirationTimeBeforeCommit; + requestPaint(); + tracing.__interactionsRef.current = prevInteractions; + executionContext = childExpirationTimeBeforeCommit; } else (root.current = finishedWork), (commitTime = now$1()); - rootDoesHavePassiveEffects - ? ((rootDoesHavePassiveEffects = !1), + if ((effectTag$jscomp$0 = rootDoesHavePassiveEffects)) + (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsExpirationTime = expirationTime)) - : finishPendingInteractions(root, expirationTime); - expirationTime = root.firstPendingTime; - 0 !== expirationTime - ? ((effectTag$jscomp$0 = requestCurrentTime()), - (effectTag$jscomp$0 = inferPriorityFromExpirationTime( - effectTag$jscomp$0, - expirationTime - )), - scheduleCallbackForRoot(root, effectTag$jscomp$0, expirationTime)) - : (legacyErrorBoundariesThatAlreadyFailed = null); + (pendingPassiveEffectsExpirationTime = expirationTime); + else + for (nextEffect = updateExpirationTimeBeforeCommit; null !== nextEffect; ) + (current$$1$jscomp$1 = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + (nextEffect = current$$1$jscomp$1); + current$$1$jscomp$1 = root.firstPendingTime; + if (0 !== current$$1$jscomp$1) { + instance$jscomp$1 = requestCurrentTime(); + instance$jscomp$1 = inferPriorityFromExpirationTime( + instance$jscomp$1, + current$$1$jscomp$1 + ); + if (null !== spawnedWorkDuringRender) + for ( + prevProps$jscomp$0 = spawnedWorkDuringRender, + spawnedWorkDuringRender = null, + updateQueue$jscomp$0 = 0; + updateQueue$jscomp$0 < prevProps$jscomp$0.length; + updateQueue$jscomp$0++ + ) + scheduleInteractions( + root, + prevProps$jscomp$0[updateQueue$jscomp$0], + root.memoizedInteractions + ); + scheduleCallbackForRoot(root, instance$jscomp$1, current$$1$jscomp$1); + } else legacyErrorBoundariesThatAlreadyFailed = null; + effectTag$jscomp$0 || finishPendingInteractions(root, expirationTime); "function" === typeof onCommitFiberRoot && - onCommitFiberRoot(finishedWork.stateNode); - 1073741823 === expirationTime + onCommitFiberRoot(finishedWork.stateNode, expirationTime); + 1073741823 === current$$1$jscomp$1 ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -5882,8 +6553,8 @@ function commitRootImpl(root, expirationTime) { (root = firstUncaughtError), (firstUncaughtError = null), root); - if (workPhase === LegacyUnbatchedPhase) return null; - flushImmediateQueue(); + if ((executionContext & LegacyUnbatchedContext) !== NoContext) return null; + flushSyncCallbackQueue(); return null; } function flushPassiveEffects() { @@ -5894,25 +6565,36 @@ function flushPassiveEffects() { pendingPassiveEffectsExpirationTime = 0; var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Cannot flush passive effects while already rendering."); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; for (var effect = root.current.firstEffect; null !== effect; ) { try { var finishedWork = effect; - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if (0 !== (finishedWork.effectTag & 512)) + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork), + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + } } catch (error) { - if (null === effect) throw ReactError("Should be working on an effect."); + if (null === effect) + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(effect, error); } - effect = effect.nextEffect; + finishedWork = effect.nextEffect; + effect.nextEffect = null; + effect = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); return !0; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -5953,11 +6635,18 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); workInProgressRoot === root && renderExpirationTime === suspendedTime - ? prepareFreshStack(root, renderExpirationTime) + ? workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ? prepareFreshStack(root, renderExpirationTime) + : (workInProgressRootHasPendingPing = !0) : root.lastPendingTime < suspendedTime || ((thenable = root.pingTime), (0 !== thenable && thenable < suspendedTime) || ((root.pingTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), (thenable = requestCurrentTime()), (thenable = inferPriorityFromExpirationTime(thenable, suspendedTime)), scheduleCallbackForRoot(root, thenable, suspendedTime))); @@ -5966,7 +6655,7 @@ function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(thenable); retryCache = requestCurrentTime(); - thenable = computeExpirationForFiber(retryCache, boundaryFiber); + thenable = computeExpirationForFiber(retryCache, boundaryFiber, null); retryCache = inferPriorityFromExpirationTime(retryCache, thenable); boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && @@ -6019,6 +6708,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, renderExpirationTime ); + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( current$$1, workInProgress, @@ -6026,6 +6720,39 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); return null !== workInProgress ? workInProgress.sibling : null; } + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); + break; + case 19: + updateExpirationTime = 0 !== (current$$1.effectTag & 64); + if (workInProgress.childExpirationTime < renderExpirationTime) + return ( + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ), + updateExpirationTime && (workInProgress.effectTag |= 64), + null + ); + if (updateExpirationTime) + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + updateExpirationTime = workInProgress.memoizedState; + null !== updateExpirationTime && + ((updateExpirationTime.rendering = null), + (updateExpirationTime.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); } return bailoutOnAlreadyFinishedWork( current$$1, @@ -6161,9 +6888,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { break; default: throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." + Error( + "Element type is invalid. Received a promise that resolves to: " + + context + + ". Lazy element type must resolve to a class or function." + ) ); } return workInProgress; @@ -6204,7 +6933,9 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime = workInProgress.updateQueue; if (null === updateExpirationTime) throw ReactError( - "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." + 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." + ) ); context = workInProgress.memoizedState; context = null !== context ? context.element : null; @@ -6360,16 +7091,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== oldValue; ) { - var list = oldValue.contextDependencies; + var list = oldValue.dependencies; if (null !== list) { getDerivedStateFromProps = oldValue.child; - for (var dependency = list.first; null !== dependency; ) { + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { if ( dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { 1 === oldValue.tag && - ((dependency = createUpdate(renderExpirationTime)), + ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), enqueueUpdate(oldValue, dependency)); oldValue.expirationTime < renderExpirationTime && @@ -6378,22 +7113,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); - dependency = renderExpirationTime; - for (var node = oldValue.return; null !== node; ) { - var alternate = node.alternate; - if (node.childExpirationTime < dependency) - (node.childExpirationTime = dependency), - null !== alternate && - alternate.childExpirationTime < dependency && - (alternate.childExpirationTime = dependency); - else if ( - null !== alternate && - alternate.childExpirationTime < dependency - ) - alternate.childExpirationTime = dependency; - else break; - node = node.return; - } + scheduleWorkOnParentPath( + oldValue.return, + renderExpirationTime + ); list.expirationTime < renderExpirationTime && (list.expirationTime = renderExpirationTime); break; @@ -6520,13 +7243,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ) ); + case 19: + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); }; -function schedulePendingInteraction(root, expirationTime) { - var interactions = tracing.__interactionsRef.current; +function scheduleInteractions(root, expirationTime, interactions) { if (0 < interactions.size) { var pendingInteractionMap = root.pendingInteractionMap, pendingInteractions = pendingInteractionMap.get(expirationTime); @@ -6547,7 +7277,7 @@ function schedulePendingInteraction(root, expirationTime) { ); } } -function startWorkOnPendingInteraction(root, expirationTime) { +function startWorkOnPendingInteractions(root, expirationTime) { var interactions = new Set(); root.pendingInteractionMap.forEach(function( scheduledInteractions, @@ -6611,6 +7341,34 @@ function finishPendingInteractions(root, committedExpirationTime) { }); } } +var onCommitFiberRoot = null, + onCommitFiberUnmount = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled || !hook.supportsFiber) return !0; + try { + var rendererID = hook.inject(internals); + onCommitFiberRoot = function(root, expirationTime) { + try { + var didError = 64 === (root.current.effectTag & 64), + currentTime = requestCurrentTime(), + priorityLevel = inferPriorityFromExpirationTime( + currentTime, + expirationTime + ); + hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); + } catch (err) {} + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) {} + }; + } catch (err) {} + return !0; +} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -6618,7 +7376,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.index = 0; this.ref = null; this.pendingProps = pendingProps; - this.contextDependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; + this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; this.effectTag = 0; this.lastEffect = this.firstEffect = this.nextEffect = null; @@ -6672,7 +7430,16 @@ function createWorkInProgress(current, pendingProps) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + pendingProps = current.dependencies; + workInProgress.dependencies = + null === pendingProps + ? null + : { + expirationTime: pendingProps.expirationTime, + firstContext: pendingProps.firstContext, + listeners: pendingProps.listeners, + responders: pendingProps.responders + }; workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; @@ -6702,12 +7469,16 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 3, expirationTime, key); + fiberTag = 8; + mode |= 7; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 2, expirationTime, key); + fiberTag = 8; + mode |= 1; + break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -6716,8 +7487,15 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.elementType = REACT_SUSPENSE_TYPE), (type.type = REACT_SUSPENSE_TYPE), + (type.elementType = REACT_SUSPENSE_TYPE), + (type.expirationTime = expirationTime), + type + ); + case REACT_SUSPENSE_LIST_TYPE: + return ( + (type = createFiber(19, pendingProps, key, mode)), + (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type ); @@ -6742,9 +7520,11 @@ function createFiberFromTypeAndProps( break a; } throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (null == type ? type : typeof type) + - "." + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (null == type ? type : typeof type) + + "." + ) ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -6758,14 +7538,6 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { elements.expirationTime = expirationTime; return elements; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - pendingProps = createFiber(8, pendingProps, key, mode); - mode = 0 === (mode & 1) ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; - pendingProps.elementType = mode; - pendingProps.type = mode; - pendingProps.expirationTime = expirationTime; - return pendingProps; -} function createFiberFromText(content, mode, expirationTime) { content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; @@ -6786,11 +7558,12 @@ function createFiberFromPortal(portal, mode, expirationTime) { }; return mode; } -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pingCache = this.pendingChildren = null; - this.pendingCommitExpirationTime = 0; + this.finishedExpirationTime = 0; this.finishedWork = null; this.timeoutHandle = -1; this.pendingContext = this.context = null; @@ -6805,10 +7578,12 @@ function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { if ("function" === typeof component.render) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } component = findCurrentHostFiber(fiber); @@ -6816,8 +7591,13 @@ function findHostInstance(component) { } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current, - currentTime = requestCurrentTime(); - current$$1 = computeExpirationForFiber(currentTime, current$$1); + currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + current$$1 = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); currentTime = container.current; a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; @@ -6827,7 +7607,9 @@ function updateContainer(element, container, parentComponent, callback) { 1 !== parentComponent.tag ) throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + 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 parentContext = parentComponent; do { @@ -6846,7 +7628,9 @@ function updateContainer(element, container, parentComponent, callback) { parentContext = parentContext.return; } while (null !== parentContext); throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (1 === parentComponent.tag) { @@ -6866,12 +7650,11 @@ function updateContainer(element, container, parentComponent, callback) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(current$$1); - callback.payload = { element: element }; + suspenseConfig = createUpdate(current$$1, suspenseConfig); + suspenseConfig.payload = { element: element }; container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - flushPassiveEffects(); - enqueueUpdate(currentTime, callback); + null !== container && (suspenseConfig.callback = container); + enqueueUpdate(currentTime, suspenseConfig); scheduleUpdateOnFiber(currentTime, current$$1); return current$$1; } @@ -6886,7 +7669,7 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } -function _inherits(subClass, superClass) { +function _inherits$1(subClass, superClass) { if ("function" !== typeof superClass && null !== superClass) throw new TypeError( "Super expression must either be null or a function, not " + @@ -6908,9 +7691,10 @@ function _inherits(subClass, superClass) { var getInspectorDataForViewTag = void 0; getInspectorDataForViewTag = function() { throw ReactError( - "getInspectorDataForViewTag() is not available in production" + Error("getInspectorDataForViewTag() is not available in production") ); }; +var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -6924,19 +7708,19 @@ function findNodeHandle(componentOrHandle) { ? componentOrHandle.canonical._nativeTag : componentOrHandle._nativeTag; } -_batchedUpdatesImpl = function(fn, a) { - if (0 !== workPhase) return fn(a); - workPhase = 1; +batchedUpdatesImpl = function(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= 1; try { return fn(a); } finally { - (workPhase = 0), flushImmediateQueue(); + (executionContext = prevExecutionContext), + executionContext === NoContext && flushSyncCallbackQueue(); } }; -_flushInteractiveUpdatesImpl = function() { - workPhase !== RenderPhase && - workPhase !== CommitPhase && - flushPendingDiscreteUpdates(); +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); }; var roots = new Map(), ReactFabric = { @@ -6955,7 +7739,7 @@ var roots = new Map(), ? this : call; } - _inherits(ReactNativeComponent, _React$Component); + _inherits$1(ReactNativeComponent, _React$Component); ReactNativeComponent.prototype.blur = function() { ReactNativePrivateInterface.TextInputState.blurTextInput( findNodeHandle(this) @@ -7051,12 +7835,21 @@ var roots = new Map(), })(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, setNativeProps: function() {}, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + null != handle._internalInstanceHandle && + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = new FiberRootNode(containerTag, !1); + root = new FiberRootNode(containerTag, 0, !1); var uninitializedFiber = 0; - isDevToolsPresent && (uninitializedFiber |= 4); + isDevToolsPresent && (uninitializedFiber |= 8); uninitializedFiber = createFiber(3, null, null, uninitializedFiber); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -7203,7 +7996,8 @@ var roots = new Map(), findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, - setRefreshHandler: null + setRefreshHandler: null, + getCurrentFiber: null }) ); })({ diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.js b/Libraries/Renderer/implementations/ReactFabric-profiling.js index 1d9cc485a5c344..8fad29f2f8c173 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -16,10 +16,9 @@ var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/R React = require("react"), Scheduler = require("scheduler"), tracing = require("scheduler/tracing"); -function ReactError(message) { - message = Error(message); - message.name = "Invariant Violation"; - return message; +function ReactError(error) { + error.name = "Invariant Violation"; + return error; } var eventPluginOrder = null, namesToPlugins = {}; @@ -30,16 +29,20 @@ function recomputePluginOrdering() { pluginIndex = eventPluginOrder.indexOf(pluginName); if (!(-1 < pluginIndex)) throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); if (!plugins[pluginIndex]) { if (!pluginModule.extractEvents) throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); plugins[pluginIndex] = pluginModule; pluginIndex = pluginModule.eventTypes; @@ -50,9 +53,11 @@ function recomputePluginOrdering() { eventName$jscomp$0 = eventName; if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ) ); eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -78,11 +83,13 @@ function recomputePluginOrdering() { : (JSCompiler_inline_result = !1); if (!JSCompiler_inline_result) throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } } @@ -91,9 +98,11 @@ function recomputePluginOrdering() { function publishRegistrationName(registrationName, pluginModule) { if (registrationNameModules[registrationName]) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); registrationNameModules[registrationName] = pluginModule; } @@ -142,7 +151,9 @@ function invokeGuardedCallbackAndCatchFirstError( caughtError = null; } else throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } @@ -160,7 +171,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; if (Array.isArray(dispatchListener)) - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null; @@ -173,7 +184,9 @@ function executeDirectDispatch(event) { function accumulateInto(current, next) { if (null == next) throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); if (null == current) return next; if (Array.isArray(current)) { @@ -210,7 +223,9 @@ var injection = { injectEventPluginOrder: function(injectedEventPluginOrder) { if (eventPluginOrder) throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); @@ -227,9 +242,11 @@ var injection = { ) { if (namesToPlugins[pluginName]) throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); namesToPlugins[pluginName] = pluginModule; isOrderingDirty = !0; @@ -271,11 +288,13 @@ function getListener(inst, registrationName) { if (inst) return null; if (listener && "function" !== typeof listener) throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); return listener; } @@ -439,7 +458,9 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { if (!(event instanceof this)) throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); event.destructor(); 10 > this.eventPool.length && this.eventPool.push(event); @@ -475,7 +496,8 @@ function timestampForTouch(touch) { } function getTouchIdentifier(_ref) { _ref = _ref.identifier; - if (null == _ref) throw ReactError("Touch object is missing identifier."); + if (null == _ref) + throw ReactError(Error("Touch object is missing identifier.")); return _ref; } function recordTouchStart(touch) { @@ -518,7 +540,7 @@ function recordTouchMove(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch move without a touch start.\nTouch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -536,7 +558,7 @@ function recordTouchEnd(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch end without a touch start.\nTouch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -590,7 +612,7 @@ var ResponderTouchHistoryStore = { function accumulate(current, next) { if (null == next) throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error("accumulate(...): Accumulated items must not be null or undefined.") ); return null == current ? next @@ -968,7 +990,9 @@ injection.injectEventPluginsByName({ directDispatchConfig = customDirectEventTypes[topLevelType]; if (!bubbleDispatchConfig && !directDispatchConfig) throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); topLevelType = SyntheticEvent.getPooled( bubbleDispatchConfig || directDispatchConfig, @@ -994,7 +1018,7 @@ getFiberCurrentPropsFromNode = function(inst) { getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { inst = inst.stateNode.canonical._nativeTag; - if (!inst) throw ReactError("All native instances should have a tag."); + if (!inst) throw ReactError(Error("All native instances should have a tag.")); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1011,6 +1035,8 @@ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher") || (ReactSharedInternals.ReactCurrentDispatcher = { current: null }); +ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig") || + (ReactSharedInternals.ReactCurrentBatchConfig = { suspense: null }); var hasSymbol = "function" === typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, @@ -1024,11 +1050,13 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, + REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; -hasSymbol && Symbol.for("react.event_component"); -hasSymbol && Symbol.for("react.event_target"); -hasSymbol && Symbol.for("react.event_target.touch_hit"); +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; @@ -1042,8 +1070,6 @@ function getComponentName(type) { if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -1054,6 +1080,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1088,14 +1116,14 @@ function isFiberMountedImpl(fiber) { } function assertIsMounted(fiber) { if (2 !== isFiberMountedImpl(fiber)) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; if (!alternate) { alternate = isFiberMountedImpl(fiber); if (3 === alternate) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return 1 === alternate ? null : fiber; } for (var a = fiber, b = alternate; ; ) { @@ -1116,7 +1144,7 @@ function findCurrentFiberUsingSlowPath(fiber) { if (parentB === b) return assertIsMounted(parentA), alternate; parentB = parentB.sibling; } - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } if (a.return !== b.return) (a = parentA), (b = parentB); else { @@ -1153,17 +1181,21 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (!didFindChild) throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } } if (a.alternate !== b) throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (3 !== a.tag) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return a.stateNode.current === a ? fiber : alternate; } function findCurrentHostFiber(parent) { @@ -1416,23 +1448,28 @@ var restoreTarget = null, function restoreStateOfTarget(target) { if (getInstanceFromNode(target)) throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } -function _batchedUpdatesImpl(fn, bookkeeping) { +function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } -function _flushInteractiveUpdatesImpl() {} -var isBatching = !1; +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { - if (isBatching) return fn(bookkeeping); - isBatching = !0; + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - if (((isBatching = !1), null !== restoreTarget || null !== restoreQueue)) + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) if ( - (_flushInteractiveUpdatesImpl(), + (flushDiscreteUpdatesImpl(), restoreTarget && ((bookkeeping = restoreTarget), (fn = restoreQueue), @@ -1444,6 +1481,51 @@ function batchedUpdates(fn, bookkeeping) { restoreStateOfTarget(fn[bookkeeping]); } } +function _inherits(subClass, superClass) { + if ("function" !== typeof superClass && null !== superClass) + throw new TypeError( + "Super expression must either be null or a function, not " + + typeof superClass + ); + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: !1, + writable: !0, + configurable: !0 + } + }); + superClass && + (Object.setPrototypeOf + ? Object.setPrototypeOf(subClass, superClass) + : (subClass.__proto__ = superClass)); +} +(function(_React$Component) { + function ReactNativeComponent() { + if (!(this instanceof ReactNativeComponent)) + throw new TypeError("Cannot call a class as a function"); + var call = _React$Component.apply(this, arguments); + if (!this) + throw new ReferenceError( + "this hasn't been initialised - super() hasn't been called" + ); + return !call || ("object" !== typeof call && "function" !== typeof call) + ? this + : call; + } + _inherits(ReactNativeComponent, _React$Component); + ReactNativeComponent.prototype.blur = function() {}; + ReactNativeComponent.prototype.focus = function() {}; + ReactNativeComponent.prototype.measure = function() {}; + ReactNativeComponent.prototype.measureInWindow = function() {}; + ReactNativeComponent.prototype.measureLayout = function() {}; + ReactNativeComponent.prototype.setNativeProps = function() {}; + return ReactNativeComponent; +})(React.Component); +new Map(); +new Map(); +new Set(); +new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { batchedUpdates(function() { var events = nativeEvent.target; @@ -1466,7 +1548,9 @@ function dispatchEvent(target, topLevelType, nativeEvent) { forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); if (eventQueue) throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); if (hasRethrowError) throw ((events = rethrowError), @@ -1478,24 +1562,26 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } function shim$1() { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, +var _nativeFabricUIManage$1 = nativeFabricUIManager, + createNode = _nativeFabricUIManage$1.createNode, + cloneNode = _nativeFabricUIManage$1.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage$1.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, + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage$1.createChildSet, + appendChildNode = _nativeFabricUIManage$1.appendChild, + appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, + completeRoot = _nativeFabricUIManage$1.completeRoot, + registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, + fabricMeasure = _nativeFabricUIManage$1.measure, + fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1557,7 +1643,7 @@ function createTextInstance( ) { if (!hostContext.isInAParentText) throw ReactError( - "Text strings must be rendered within a component." + Error("Text strings must be rendered within a component.") ); hostContext = nextReactTag; nextReactTag += 2; @@ -1672,7 +1758,9 @@ function popTopLevelContextObject(fiber) { function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); @@ -1685,10 +1773,12 @@ function processChildContext(fiber, type, parentContext) { for (var contextKey in instance) if (!(contextKey in fiber)) throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); return Object.assign({}, parentContext, instance); } @@ -1710,7 +1800,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { var instance = workInProgress.stateNode; if (!instance) throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); didChange ? ((type = processChildContext(workInProgress, type, previousContext)), @@ -1721,40 +1813,11 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -var onCommitFiberRoot = null, - onCommitFiberUnmount = null; -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) {} - }; -} -var isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; -function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - var rendererID = hook.inject(internals); - onCommitFiberRoot = catchErrors(function(root) { - hook.onCommitFiberRoot( - rendererID, - root, - void 0, - 64 === (root.current.effectTag & 64) - ); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) {} - return !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 = Scheduler.unstable_now, Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel, @@ -1768,12 +1831,16 @@ if ( null == tracing.__interactionsRef.current ) throw ReactError( - "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 http://fb.me/react-profiling" + 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 http://fb.me/react-profiling" + ) ); var fakeCallbackNode = {}, - immediateQueue = null, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, immediateQueueCallbackNode = null, - isFlushingImmediate = !1, + isFlushingSyncQueue = !1, initialTimeMs = Scheduler_now(), now = 1e4 > initialTimeMs @@ -1794,7 +1861,7 @@ function getCurrentPriorityLevel() { case Scheduler_IdlePriority: return 95; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function reactPriorityToSchedulerPriority(reactPriorityLevel) { @@ -1810,54 +1877,55 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case 95: return Scheduler_IdlePriority; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (99 === reactPriorityLevel) - return ( - null === immediateQueue - ? ((immediateQueue = [callback]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ))) - : immediateQueue.push(callback), - fakeCallbackNode - ); reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function flushImmediateQueue() { +function scheduleSyncCallback(callback) { + null === syncQueue + ? ((syncQueue = [callback]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(callback); + return fakeCallbackNode; +} +function flushSyncCallbackQueue() { null !== immediateQueueCallbackNode && Scheduler_cancelCallback(immediateQueueCallbackNode); - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && null !== immediateQueue) { - isFlushingImmediate = !0; +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; var i = 0; try { - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do callback = callback(!0); - while (null !== callback); - } - immediateQueue = null; + var queue = syncQueue; + runWithPriority$1(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; } catch (error) { - throw (null !== immediateQueue && - (immediateQueue = immediateQueue.slice(i + 1)), + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ), error); } finally { - isFlushingImmediate = !1; + isFlushingSyncQueue = !1; } } } @@ -1865,7 +1933,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (1073741823 === expirationTime) return 99; if (1 === expirationTime) return 95; currentTime = - 10 * (1073741822 - expirationTime) - 10 * (1073741822 - currentTime); + 10 * (1073741821 - expirationTime) - 10 * (1073741821 - currentTime); return 0 >= currentTime ? 99 : 250 >= currentTime @@ -1947,7 +2015,7 @@ var valueCursor = { current: null }, currentlyRenderingFiber = null, lastContextDependency = null, lastContextWithAllBitsObserved = null; -function resetContextDependences() { +function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } function pushProvider(providerFiber, nextValue) { @@ -1960,14 +2028,32 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); providerFiber.type._context._currentValue2 = currentValue; } +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + for (; null !== parent; ) { + var alternate = parent.alternate; + if (parent.childExpirationTime < renderExpirationTime) + (parent.childExpirationTime = renderExpirationTime), + null !== alternate && + alternate.childExpirationTime < renderExpirationTime && + (alternate.childExpirationTime = renderExpirationTime); + else if ( + null !== alternate && + alternate.childExpirationTime < renderExpirationTime + ) + alternate.childExpirationTime = renderExpirationTime; + else break; + parent = parent.return; + } +} function prepareToReadContext(workInProgress, renderExpirationTime) { currentlyRenderingFiber = workInProgress; lastContextWithAllBitsObserved = lastContextDependency = null; - var currentDependencies = workInProgress.contextDependencies; - null !== currentDependencies && - currentDependencies.expirationTime >= renderExpirationTime && - (didReceiveUpdate = !0); - workInProgress.contextDependencies = null; + workInProgress = workInProgress.dependencies; + null !== workInProgress && + null !== workInProgress.firstContext && + (workInProgress.expirationTime >= renderExpirationTime && + (didReceiveUpdate = !0), + (workInProgress.firstContext = null)); } function readContext(context, observedBits) { if ( @@ -1981,12 +2067,16 @@ function readContext(context, observedBits) { if (null === lastContextDependency) { if (null === currentlyRenderingFiber) throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); lastContextDependency = observedBits; - currentlyRenderingFiber.contextDependencies = { - first: observedBits, - expirationTime: 0 + currentlyRenderingFiber.dependencies = { + expirationTime: 0, + firstContext: observedBits, + listeners: null, + responders: null }; } else lastContextDependency = lastContextDependency.next = observedBits; } @@ -2019,9 +2109,10 @@ function cloneUpdateQueue(currentQueue) { lastCapturedEffect: null }; } -function createUpdate(expirationTime) { +function createUpdate(expirationTime, suspenseConfig) { return { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, @@ -2137,8 +2228,10 @@ function processUpdateQueue( ((newFirstUpdate = update), (newBaseState = resultState)), newExpirationTime < updateExpirationTime && (newExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), (resultState = getStateFromUpdate( workInProgress, queue, @@ -2214,15 +2307,18 @@ function commitUpdateEffects(effect, instance) { var context = instance; if ("function" !== typeof _callback3) throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - _callback3 + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + _callback3 + ) ); _callback3.call(context); } effect = effect.nextEffect; } } -var emptyRefsObject = new React.Component().refs; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + emptyRefsObject = new React.Component().refs; function applyDerivedStateFromProps( workInProgress, ctor, @@ -2249,36 +2345,42 @@ var classComponentUpdater = { }, enqueueSetState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 1; + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 2; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 2; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); } }; @@ -2407,15 +2509,19 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); inst = element.stateNode; } if (!inst) throw ReactError( - "Missing owner for string ref " + - returnFiber + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + returnFiber + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); var stringRef = "" + returnFiber; if ( @@ -2435,13 +2541,17 @@ function coerceRef(returnFiber, current$$1, element) { } if ("string" !== typeof returnFiber) throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); if (!element._owner) throw ReactError( - "Element ref was specified as a string (" + - returnFiber + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + returnFiber + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } return returnFiber; @@ -2449,11 +2559,13 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) throw ReactError( - "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === Object.prototype.toString.call(newChild) + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + ) ); } function ChildReconciler(shouldTrackSideEffects) { @@ -2856,11 +2968,13 @@ function ChildReconciler(shouldTrackSideEffects) { var iteratorFn = getIteratorFn(newChildrenIterable); if ("function" !== typeof iteratorFn) throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); newChildrenIterable = iteratorFn.call(newChildrenIterable); if (null == newChildrenIterable) - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); for ( var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, @@ -3095,8 +3209,10 @@ function ChildReconciler(shouldTrackSideEffects) { case 0: throw ((returnFiber = returnFiber.type), ReactError( - (returnFiber.displayName || returnFiber.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (returnFiber.displayName || returnFiber.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) )); } return deleteRemainingChildren(returnFiber, currentFirstChild); @@ -3111,7 +3227,9 @@ var reconcileChildFibers = ChildReconciler(!0), function requiredContext(c) { if (c === NO_CONTEXT) throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); return c; } @@ -3149,6 +3267,50 @@ function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } +var SubtreeSuspenseContextMask = 1, + InvisibleParentSuspenseContext = 1, + ForceSuspenseFallback = 2, + suspenseStackCursor = { current: 0 }; +function findFirstSuspended(row) { + for (var node = row; null !== node; ) { + if (13 === node.tag) { + if (null !== node.memoizedState) return node; + } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { + if (0 !== (node.effectTag & 64)) return node; + } else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; +} +var currentListenerHookIndex = 0; +function updateListenerHook(responder, props) { + var dependencies = null.dependencies; + null === dependencies && + (dependencies = null.dependencies = { + expirationTime: 0, + firstContext: null, + listeners: [], + responders: null + }); + var listeners = dependencies.listeners; + null === listeners && (dependencies.listeners = listeners = []); + listeners.length === currentListenerHookIndex + ? (listeners.push({ responder: responder, props: props }), + currentListenerHookIndex++) + : ((listeners = listeners[currentListenerHookIndex++]), + (listeners.responder = responder), + (listeners.props = props)); +} var NoEffect$1 = 0, UnmountSnapshot = 2, UnmountMutation = 4, @@ -3173,7 +3335,9 @@ var NoEffect$1 = 0, numberOfReRenders = 0; function throwInvalidHookError() { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } function areHookInputsEqual(nextDeps, prevDeps) { @@ -3223,7 +3387,9 @@ function renderWithHooks( sideEffectTag = 0; if (current) throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); return workInProgress; } @@ -3259,7 +3425,9 @@ function updateWorkInProgressHook() { (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) - throw ReactError("Rendered more hooks than during the previous render."); + throw ReactError( + Error("Rendered more hooks than during the previous render.") + ); currentHook = nextCurrentHook; var newHook = { memoizedState: currentHook.memoizedState, @@ -3284,7 +3452,9 @@ function updateReducer(reducer) { queue = hook.queue; if (null === queue) throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); queue.lastRenderedReducer = reducer; if (0 < numberOfReRenders) { @@ -3327,8 +3497,10 @@ function updateReducer(reducer) { (firstRenderPhaseUpdate = newState)), updateExpirationTime > remainingExpirationTime && (remainingExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ), (newState = _update.eagerReducer === reducer ? _update.eagerState @@ -3407,7 +3579,9 @@ function mountDebugValue() {} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); var alternate = fiber.alternate; if ( @@ -3418,6 +3592,7 @@ function dispatchAction(fiber, queue, action) { ((didScheduleRenderPhaseUpdate = !0), (fiber = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, @@ -3433,24 +3608,29 @@ function dispatchAction(fiber, queue, action) { queue.next = fiber; } else { - flushPassiveEffects(); - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, fiber); - var _update2 = { - expirationTime: currentTime, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }, - _last = queue.last; - if (null === _last) _update2.next = _update2; + var currentTime = requestCurrentTime(), + _suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); + _suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: _suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var _last = queue.last; + if (null === _last) _suspenseConfig.next = _suspenseConfig; else { var first = _last.next; - null !== first && (_update2.next = first); - _last.next = _update2; + null !== first && (_suspenseConfig.next = first); + _last.next = _suspenseConfig; } - queue.last = _update2; + queue.last = _suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3459,8 +3639,8 @@ function dispatchAction(fiber, queue, action) { try { var currentState = queue.lastRenderedState, _eagerState = alternate(currentState, action); - _update2.eagerReducer = alternate; - _update2.eagerState = _eagerState; + _suspenseConfig.eagerReducer = alternate; + _suspenseConfig.eagerState = _eagerState; if (is(_eagerState, currentState)) return; } catch (error) { } finally { @@ -3479,7 +3659,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3552,7 +3733,8 @@ var ContextOnlyDispatcher = { ); return [hook.memoizedState, initialState]; }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, HooksDispatcherOnUpdate = { readContext: readContext, @@ -3606,7 +3788,8 @@ var ContextOnlyDispatcher = { useState: function(initialState) { return updateReducer(basicStateReducer, initialState); }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -4162,6 +4345,7 @@ function pushHostRootContext(workInProgress) { pushTopLevelContextObject(workInProgress, root.context, !1); pushHostContainer(workInProgress, root.containerInfo); } +var SUSPENDED_MARKER = {}; function updateSuspenseComponent( current$$1, workInProgress, @@ -4169,35 +4353,50 @@ function updateSuspenseComponent( ) { var mode = workInProgress.mode, nextProps = workInProgress.pendingProps, - nextState = workInProgress.memoizedState; - if (0 === (workInProgress.effectTag & 64)) { - nextState = null; - var nextDidTimeout = !1; - } else - (nextState = { - fallbackExpirationTime: - null !== nextState ? nextState.fallbackExpirationTime : 0 - }), + suspenseContext = suspenseStackCursor.current, + nextState = null, + nextDidTimeout = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || + (JSCompiler_temp = + 0 !== (suspenseContext & ForceSuspenseFallback) && + (null === current$$1 || null !== current$$1.memoizedState)); + JSCompiler_temp + ? ((nextState = SUSPENDED_MARKER), (nextDidTimeout = !0), - (workInProgress.effectTag &= -65); + (workInProgress.effectTag &= -65)) + : (null !== current$$1 && null === current$$1.memoizedState) || + void 0 === nextProps.fallback || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= InvisibleParentSuspenseContext); + suspenseContext &= SubtreeSuspenseContextMask; + push(suspenseStackCursor, suspenseContext, workInProgress); if (null === current$$1) if (nextDidTimeout) { - var nextFallbackChildren = nextProps.fallback; + nextProps = nextProps.fallback; current$$1 = createFiberFromFragment(null, mode, 0, null); - 0 === (workInProgress.mode & 1) && - (current$$1.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child); + current$$1.return = workInProgress; + if (0 === (workInProgress.mode & 2)) + for ( + nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + current$$1.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = current$$1), + (nextDidTimeout = nextDidTimeout.sibling); renderExpirationTime = createFiberFromFragment( - nextFallbackChildren, + nextProps, mode, renderExpirationTime, null ); + renderExpirationTime.return = workInProgress; current$$1.sibling = renderExpirationTime; mode = current$$1; - mode.return = renderExpirationTime.return = workInProgress; } else mode = renderExpirationTime = mountChildFibers( workInProgress, @@ -4208,95 +4407,235 @@ function updateSuspenseComponent( else { if (null !== current$$1.memoizedState) if ( - ((nextFallbackChildren = current$$1.child), - (mode = nextFallbackChildren.sibling), + ((suspenseContext = current$$1.child), + (mode = suspenseContext.sibling), nextDidTimeout) ) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - nextFallbackChildren, - nextFallbackChildren.pendingProps, + suspenseContext, + suspenseContext.pendingProps, 0 ); - 0 === (workInProgress.mode & 1) && + renderExpirationTime.return = workInProgress; + if ( + 0 === (workInProgress.mode & 2) && ((nextDidTimeout = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== nextFallbackChildren.child && - (renderExpirationTime.child = nextDidTimeout)); - if (workInProgress.mode & 4) { - nextFallbackChildren = 0; + nextDidTimeout !== suspenseContext.child) + ) for ( - nextDidTimeout = renderExpirationTime.child; + renderExpirationTime.child = nextDidTimeout; null !== nextDidTimeout; ) - (nextFallbackChildren += nextDidTimeout.treeBaseDuration), + (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - renderExpirationTime.treeBaseDuration = nextFallbackChildren; + if (workInProgress.mode & 8) { + nextDidTimeout = 0; + for ( + suspenseContext = renderExpirationTime.child; + null !== suspenseContext; + + ) + (nextDidTimeout += suspenseContext.treeBaseDuration), + (suspenseContext = suspenseContext.sibling); + renderExpirationTime.treeBaseDuration = nextDidTimeout; } - nextFallbackChildren = renderExpirationTime.sibling = createWorkInProgress( - mode, - nextProps, - mode.expirationTime - ); + nextProps = createWorkInProgress(mode, nextProps, mode.expirationTime); + nextProps.return = workInProgress; + renderExpirationTime.sibling = nextProps; mode = renderExpirationTime; renderExpirationTime.childExpirationTime = 0; - renderExpirationTime = nextFallbackChildren; - mode.return = renderExpirationTime.return = workInProgress; + renderExpirationTime = nextProps; } else mode = renderExpirationTime = reconcileChildFibers( workInProgress, - nextFallbackChildren.child, + suspenseContext.child, nextProps.children, renderExpirationTime ); - else { - var _currentPrimaryChild = current$$1.child; - if (nextDidTimeout) { - nextProps = nextProps.fallback; - nextFallbackChildren = createFiberFromFragment(null, mode, 0, null); - nextFallbackChildren.child = _currentPrimaryChild; - 0 === (workInProgress.mode & 1) && - (nextFallbackChildren.child = + else if (((suspenseContext = current$$1.child), nextDidTimeout)) { + nextDidTimeout = nextProps.fallback; + nextProps = createFiberFromFragment(null, mode, 0, null); + nextProps.return = workInProgress; + nextProps.child = suspenseContext; + null !== suspenseContext && (suspenseContext.return = nextProps); + if (0 === (workInProgress.mode & 2)) + for ( + suspenseContext = null !== workInProgress.memoizedState ? workInProgress.child.child - : workInProgress.child); - if (workInProgress.mode & 4) { - nextDidTimeout = 0; - for ( - _currentPrimaryChild = nextFallbackChildren.child; - null !== _currentPrimaryChild; + : workInProgress.child, + nextProps.child = suspenseContext; + null !== suspenseContext; + ) + (suspenseContext.return = nextProps), + (suspenseContext = suspenseContext.sibling); + if (workInProgress.mode & 8) { + suspenseContext = 0; + for (JSCompiler_temp = nextProps.child; null !== JSCompiler_temp; ) + (suspenseContext += JSCompiler_temp.treeBaseDuration), + (JSCompiler_temp = JSCompiler_temp.sibling); + nextProps.treeBaseDuration = suspenseContext; + } + renderExpirationTime = createFiberFromFragment( + nextDidTimeout, + mode, + renderExpirationTime, + null + ); + renderExpirationTime.return = workInProgress; + nextProps.sibling = renderExpirationTime; + renderExpirationTime.effectTag |= 2; + mode = nextProps; + nextProps.childExpirationTime = 0; + } else + renderExpirationTime = mode = reconcileChildFibers( + workInProgress, + suspenseContext, + nextProps.children, + renderExpirationTime + ); + workInProgress.stateNode = current$$1.stateNode; + } + workInProgress.memoizedState = nextState; + workInProgress.child = mode; + return renderExpirationTime; +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailExpiration = 0), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren( + current$$1, + workInProgress, + nextProps.children, + renderExpirationTime + ); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & ForceSuspenseFallback)) + (nextProps = + (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), + (workInProgress.effectTag |= 64); + else { + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) { + if (null !== current$$1.memoizedState) { + current$$1.expirationTime < renderExpirationTime && + (current$$1.expirationTime = renderExpirationTime); + var alternate = current$$1.alternate; + null !== alternate && + alternate.expirationTime < renderExpirationTime && + (alternate.expirationTime = renderExpirationTime); + scheduleWorkOnParentPath(current$$1.return, renderExpirationTime); + } + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress ) - (nextDidTimeout += _currentPrimaryChild.treeBaseDuration), - (_currentPrimaryChild = _currentPrimaryChild.sibling); - nextFallbackChildren.treeBaseDuration = nextDidTimeout; + break a; + current$$1 = current$$1.return; } - renderExpirationTime = nextFallbackChildren.sibling = createFiberFromFragment( - nextProps, - mode, + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + nextProps &= SubtreeSuspenseContextMask; + } + push(suspenseStackCursor, nextProps, workInProgress); + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderExpirationTime = workInProgress.child; + for (revealOrder = null; null !== renderExpirationTime; ) + (nextProps = renderExpirationTime.alternate), + null !== nextProps && + null === findFirstSuspended(nextProps) && + (revealOrder = renderExpirationTime), + (renderExpirationTime = renderExpirationTime.sibling); + renderExpirationTime = revealOrder; + null === renderExpirationTime + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderExpirationTime.sibling), + (renderExpirationTime.sibling = null)); + initSuspenseListRenderState( + workInProgress, + !1, + revealOrder, renderExpirationTime, - null + tailMode ); - renderExpirationTime.effectTag |= 2; - mode = nextFallbackChildren; - nextFallbackChildren.childExpirationTime = 0; - mode.return = renderExpirationTime.return = workInProgress; - } else - renderExpirationTime = mode = reconcileChildFibers( + break; + case "backwards": + renderExpirationTime = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + nextProps = revealOrder.alternate; + if (null !== nextProps && null === findFirstSuspended(nextProps)) { + workInProgress.child = revealOrder; + break; + } + nextProps = revealOrder.sibling; + revealOrder.sibling = renderExpirationTime; + renderExpirationTime = revealOrder; + revealOrder = nextProps; + } + initSuspenseListRenderState( workInProgress, - _currentPrimaryChild, - nextProps.children, - renderExpirationTime + !0, + renderExpirationTime, + null, + tailMode ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; } - workInProgress.stateNode = current$$1.stateNode; - } - workInProgress.memoizedState = nextState; - workInProgress.child = mode; - return renderExpirationTime; + return workInProgress.child; } function bailoutOnAlreadyFinishedWork( current$$1, @@ -4304,11 +4643,11 @@ function bailoutOnAlreadyFinishedWork( renderExpirationTime ) { null !== current$$1 && - (workInProgress.contextDependencies = current$$1.contextDependencies); + (workInProgress.dependencies = current$$1.dependencies); profilerStartTime = -1; if (workInProgress.childExpirationTime < renderExpirationTime) return null; if (null !== current$$1 && workInProgress.child !== current$$1.child) - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); if (null !== workInProgress.child) { current$$1 = workInProgress.child; renderExpirationTime = createWorkInProgress( @@ -4519,6 +4858,30 @@ updateHostText$1 = function(current, workInProgress, oldText, newText) { )), (workInProgress.effectTag |= 4)); }; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var _lastTailNode = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === _lastTailNode + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (_lastTailNode.sibling = null); + } +} function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4545,15 +4908,17 @@ function completeWork(current, workInProgress, renderExpirationTime) { break; case 5: popHostContext(workInProgress); - renderExpirationTime = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - type, + renderExpirationTime, newProps, - renderExpirationTime + rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); @@ -4561,33 +4926,35 @@ function completeWork(current, workInProgress, renderExpirationTime) { requiredContext(contextStackCursor$1.current); current = nextReactTag; nextReactTag += 2; - type = getViewConfigForType(type); + renderExpirationTime = getViewConfigForType(renderExpirationTime); var updatePayload = diffProperties( null, emptyObject, newProps, - type.validAttributes + renderExpirationTime.validAttributes ); - renderExpirationTime = createNode( + rootContainerInstance = createNode( current, - type.uiViewClassName, - renderExpirationTime, + renderExpirationTime.uiViewClassName, + rootContainerInstance, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - type, + renderExpirationTime, newProps, workInProgress ); - current = { node: renderExpirationTime, canonical: current }; + current = { node: rootContainerInstance, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; null !== workInProgress.ref && (workInProgress.effectTag |= 128); } else if (null === workInProgress.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -4601,14 +4968,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { else { if ("string" !== typeof newProps && null === workInProgress.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); current = requiredContext(rootInstanceStackCursor.current); - renderExpirationTime = requiredContext(contextStackCursor$1.current); + rootContainerInstance = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - renderExpirationTime, + rootContainerInstance, workInProgress ); } @@ -4616,35 +4985,41 @@ function completeWork(current, workInProgress, renderExpirationTime) { case 11: break; case 13: + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( (workInProgress.expirationTime = renderExpirationTime), workInProgress ); newProps = null !== newProps; - renderExpirationTime = !1; + rootContainerInstance = !1; null !== current && - ((type = current.memoizedState), - (renderExpirationTime = null !== type), + ((renderExpirationTime = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime), newProps || - null === type || - ((type = type.fallbackExpirationTime), - type < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = type), - (current = current.child.sibling), - null !== current && - ((type = workInProgress.firstEffect), - null !== type - ? ((workInProgress.firstEffect = current), - (current.nextEffect = type)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = current), - (current.nextEffect = null)), - (current.effectTag = 8)))); - newProps && - !renderExpirationTime && - 0 !== (workInProgress.mode & 1) && - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); + null === renderExpirationTime || + ((renderExpirationTime = current.child.sibling), + null !== renderExpirationTime && + ((updatePayload = workInProgress.firstEffect), + null !== updatePayload + ? ((workInProgress.firstEffect = renderExpirationTime), + (renderExpirationTime.nextEffect = updatePayload)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), + (renderExpirationTime.nextEffect = null)), + (renderExpirationTime.effectTag = 8)))); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & InvisibleParentSuspenseContext) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; newProps && (workInProgress.effectTag |= 4); break; case 7: @@ -4670,16 +5045,196 @@ function completeWork(current, workInProgress, renderExpirationTime) { case 18: break; case 19: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (null === newProps) break; + rootContainerInstance = 0 !== (workInProgress.effectTag & 64); + updatePayload = newProps.rendering; + if (null === updatePayload) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + workInProgress.firstEffect = workInProgress.lastEffect = null; + current = renderExpirationTime; + for (newProps = workInProgress.child; null !== newProps; ) + (rootContainerInstance = newProps), + (updatePayload = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (renderExpirationTime = rootContainerInstance.alternate), + null === renderExpirationTime + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = updatePayload), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null), + (rootContainerInstance.selfBaseDuration = 0), + (rootContainerInstance.treeBaseDuration = 0)) + : ((rootContainerInstance.childExpirationTime = + renderExpirationTime.childExpirationTime), + (rootContainerInstance.expirationTime = + renderExpirationTime.expirationTime), + (rootContainerInstance.child = + renderExpirationTime.child), + (rootContainerInstance.memoizedProps = + renderExpirationTime.memoizedProps), + (rootContainerInstance.memoizedState = + renderExpirationTime.memoizedState), + (rootContainerInstance.updateQueue = + renderExpirationTime.updateQueue), + (updatePayload = renderExpirationTime.dependencies), + (rootContainerInstance.dependencies = + null === updatePayload + ? null + : { + expirationTime: updatePayload.expirationTime, + firstContext: updatePayload.firstContext, + listeners: updatePayload.listeners, + responders: updatePayload.responders + }), + (rootContainerInstance.selfBaseDuration = + renderExpirationTime.selfBaseDuration), + (rootContainerInstance.treeBaseDuration = + renderExpirationTime.treeBaseDuration)), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & SubtreeSuspenseContextMask) | + ForceSuspenseFallback, + workInProgress + ); + return workInProgress.child; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && "hidden" === newProps.tailMode) + ) { + current = current.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + workInProgress = workInProgress.lastEffect = newProps.lastEffect; + null !== workInProgress && (workInProgress.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime && + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (current = renderExpirationTime - 1), + (workInProgress.expirationTime = workInProgress.childExpirationTime = current), + null === spawnedWorkDuringRender + ? (spawnedWorkDuringRender = [current]) + : spawnedWorkDuringRender.push(current)); + newProps.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = newProps.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (newProps.last = updatePayload)); + } + if (null !== newProps.tail) + return ( + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500), + (current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (current.sibling = null), + (newProps = suspenseStackCursor.current), + (newProps = rootContainerInstance + ? (newProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback + : newProps & SubtreeSuspenseContextMask), + push(suspenseStackCursor, newProps, workInProgress), + current + ); break; case 20: break; default: throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } return null; } +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + workInProgress.effectTag = (effectTag & -2049) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null + ); + case 18: + return null; + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} function createCapturedValue(value, source) { return { value: value, @@ -4687,24 +5242,18 @@ function createCapturedValue(value, source) { stack: getStackByFiberInDevAndProd(source) }; } +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") + ); function logCapturedError(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - if (error instanceof Error) { - capturedError = error.message; - var name = error.name; - try { - error.message = - (capturedError ? name + ": " + capturedError : name) + - "\n\nThis error is located at:" + - componentStack; - } catch (e) {} - } else - error = - "string" === typeof error - ? Error(error + "\n\nThis error is located at:" + componentStack) - : Error("Unspecified error at:" + componentStack); - ReactNativePrivateInterface.ExceptionsManager.handleException(error, !1); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ) && console.error(capturedError.error); } var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; function logError(boundary, errorInfo) { @@ -4775,7 +5324,12 @@ function commitWork(current$$1, finishedWork) { case 12: return; case 13: - commitSuspenseComponent(finishedWork); + null !== finishedWork.memoizedState && + (globalMostRecentFallbackTime = now()); + attachSuspenseRetryListeners(finishedWork); + return; + case 19: + attachSuspenseRetryListeners(finishedWork); return; } switch (finishedWork.tag) { @@ -4783,29 +5337,26 @@ function commitWork(current$$1, finishedWork) { case 5: case 6: case 20: - case 19: break; case 3: case 4: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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 commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; - null !== newState && - 0 === newState.fallbackExpirationTime && - (newState.fallbackExpirationTime = requestCurrentTime() - 500); - newState = finishedWork.updateQueue; - if (null !== newState) { +function attachSuspenseRetryListeners(finishedWork) { + var thenables = finishedWork.updateQueue; + if (null !== thenables) { finishedWork.updateQueue = null; var retryCache = finishedWork.stateNode; null === retryCache && (retryCache = finishedWork.stateNode = new PossiblyWeakSet$1()); - newState.forEach(function(thenable) { + thenables.forEach(function(thenable) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); retryCache.has(thenable) || ((retry = tracing.unstable_wrap(retry)), @@ -4816,7 +5367,7 @@ function commitSuspenseComponent(finishedWork) { } var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; expirationTime.payload = { element: null }; var error = errorInfo.value; @@ -4827,7 +5378,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { @@ -4853,64 +5404,29 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { }); return expirationTime; } -function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null; - case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -2049) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: - return ( - (effectTag = workInProgress.effectTag), - effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null - ); - case 18: - return null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 19: - case 20: - return null; - default: - return null; - } -} var ceil = Math.ceil, ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - LegacyUnbatchedPhase = 2, - RenderPhase = 4, - CommitPhase = 5, + NoContext = 0, + LegacyUnbatchedContext = 8, + RenderContext = 16, + CommitContext = 32, RootIncomplete = 0, RootErrored = 1, RootSuspended = 2, - RootCompleted = 3, - workPhase = 0, + RootSuspendedWithDelay = 3, + RootCompleted = 4, + executionContext = NoContext, workInProgressRoot = null, workInProgress = null, renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, - workInProgressRootMostRecentEventTime = 1073741823, + workInProgressRootLatestProcessedExpirationTime = 1073741823, + workInProgressRootLatestSuspenseTimeout = 1073741823, + workInProgressRootCanSuspendUsingConfig = null, + workInProgressRootHasPendingPing = !1, + globalMostRecentFallbackTime = 0, + FALLBACK_THROTTLE_MS = 500, nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, @@ -4921,36 +5437,52 @@ var ceil = Math.ceil, rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, + spawnedWorkDuringRender = null, currentEventTime = 0; function requestCurrentTime() { - return workPhase === RenderPhase || workPhase === CommitPhase - ? 1073741822 - ((now() / 10) | 0) + return (executionContext & (RenderContext | CommitContext)) !== NoContext + ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime ? currentEventTime - : (currentEventTime = 1073741822 - ((now() / 10) | 0)); -} -function computeExpirationForFiber(currentTime, fiber) { - if (0 === (fiber.mode & 1)) return 1073741823; - if (workPhase === RenderPhase) return renderExpirationTime; - switch (getCurrentPriorityLevel()) { - case 99: - currentTime = 1073741823; - break; - case 98: - currentTime = - 1073741822 - 10 * ((((1073741822 - currentTime + 15) / 10) | 0) + 1); - break; - case 97: - case 96: - currentTime = - 1073741822 - 25 * ((((1073741822 - currentTime + 500) / 25) | 0) + 1); - break; - case 95: - currentTime = 1; - break; - default: - throw ReactError("Expected a valid priority level"); - } + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); +} +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + fiber = fiber.mode; + if (0 === (fiber & 2)) return 1073741823; + var priorityLevel = getCurrentPriorityLevel(); + if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; + if ((executionContext & RenderContext) !== NoContext) + return renderExpirationTime; + if (null !== suspenseConfig) + currentTime = + 1073741821 - + 25 * + ((((1073741821 - + currentTime + + (suspenseConfig.timeoutMs | 0 || 5e3) / 10) / + 25) | + 0) + + 1); + else + switch (priorityLevel) { + case 99: + currentTime = 1073741823; + break; + case 98: + currentTime = + 1073741821 - 10 * ((((1073741821 - currentTime + 15) / 10) | 0) + 1); + break; + case 97: + case 96: + currentTime = + 1073741821 - 25 * ((((1073741821 - currentTime + 500) / 25) | 0) + 1); + break; + case 95: + currentTime = 1; + break; + default: + throw ReactError(Error("Expected a valid priority level")); + } null !== workInProgressRoot && currentTime === renderExpirationTime && --currentTime; @@ -4961,33 +5493,42 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) )); fiber = markUpdateTimeFromFiberToRoot(fiber, expirationTime); - if (null !== fiber) - if (((fiber.pingTime = 0), 1073741823 === expirationTime)) - if (workPhase === LegacyUnbatchedPhase) + if (null !== fiber) { + fiber.pingTime = 0; + var priorityLevel = getCurrentPriorityLevel(); + if (1073741823 === expirationTime) + if ( + (executionContext & LegacyUnbatchedContext) !== NoContext && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + scheduleInteractions( + fiber, + expirationTime, + tracing.__interactionsRef.current + ); for ( - expirationTime = renderRoot(fiber, 1073741823, !0); - null !== expirationTime; + var callback = renderRoot(fiber, 1073741823, !0); + null !== callback; ) - expirationTime = expirationTime(!0); - else + callback = callback(!0); + } else scheduleCallbackForRoot(fiber, 99, 1073741823), - 0 === workPhase && flushImmediateQueue(); - else { - var priorityLevel = getCurrentPriorityLevel(); - if (98 === priorityLevel) - if (null === rootsWithPendingDiscreteUpdates) - rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]]); - else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(fiber); - (void 0 === lastDiscreteTime || lastDiscreteTime > expirationTime) && - rootsWithPendingDiscreteUpdates.set(fiber, expirationTime); - } - scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); - } + executionContext === NoContext && flushSyncCallbackQueue(); + else scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); + (executionContext & 4) === NoContext || + (98 !== priorityLevel && 99 !== priorityLevel) || + (null === rootsWithPendingDiscreteUpdates + ? (rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]])) + : ((priorityLevel = rootsWithPendingDiscreteUpdates.get(fiber)), + (void 0 === priorityLevel || priorityLevel > expirationTime) && + rootsWithPendingDiscreteUpdates.set(fiber, expirationTime))); + } } function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { fiber.expirationTime < expirationTime && @@ -5028,23 +5569,30 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode); root.callbackExpirationTime = expirationTime; - existingCallbackNode = null; - 1073741823 !== expirationTime && - 1 !== expirationTime && - ((existingCallbackNode = 10 * (1073741822 - expirationTime) - now()), - 5e3 < existingCallbackNode && (existingCallbackNode = 5e3), - (existingCallbackNode = { timeout: existingCallbackNode })); - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - existingCallbackNode - ); + 1073741823 === expirationTime + ? (root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + )) + : ((existingCallbackNode = null), + 1 !== expirationTime && + (existingCallbackNode = { + timeout: 10 * (1073741821 - expirationTime) - now() + }), + (root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + existingCallbackNode + ))); } - schedulePendingInteraction(root, expirationTime); + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); } function runRootCallback(root, callback, isSync) { var prevCallbackNode = root.callbackNode, @@ -5067,9 +5615,7 @@ function resolveLocksOnRoot(root, expirationTime) { return null !== firstBatch && firstBatch._defer && firstBatch._expirationTime >= expirationTime - ? ((root.finishedWork = root.current.alternate), - (root.pendingCommitExpirationTime = expirationTime), - scheduleCallback(97, function() { + ? (scheduleCallback(97, function() { firstBatch._onComplete(); return null; }), @@ -5081,13 +5627,14 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback(99, renderRoot.bind(null, root, expirationTime)); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = 0; + root.finishedWork = null; + root.finishedExpirationTime = 0; var timeoutHandle = root.timeoutHandle; -1 !== timeoutHandle && ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); @@ -5111,6 +5658,12 @@ function prepareFreshStack(root, expirationTime) { case 4: popHostContainer(interruptedWork); break; + case 13: + pop(suspenseStackCursor, interruptedWork); + break; + case 19: + pop(suspenseStackCursor, interruptedWork); + break; case 10: popProvider(interruptedWork); } @@ -5120,27 +5673,35 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = 1073741823; + workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = !1; + spawnedWorkDuringRender = null; } function renderRoot(root$jscomp$0, expirationTime, isSync) { - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); if (root$jscomp$0.firstPendingTime < expirationTime) return null; - if (root$jscomp$0.pendingCommitExpirationTime === expirationTime) - return ( - (root$jscomp$0.pendingCommitExpirationTime = 0), - commitRoot.bind(null, root$jscomp$0, expirationTime) - ); + if (isSync && root$jscomp$0.finishedExpirationTime === expirationTime) + return commitRoot.bind(null, root$jscomp$0); flushPassiveEffects(); if ( root$jscomp$0 !== workInProgressRoot || expirationTime !== renderExpirationTime ) prepareFreshStack(root$jscomp$0, expirationTime), - startWorkOnPendingInteraction(root$jscomp$0, expirationTime); + startWorkOnPendingInteractions(root$jscomp$0, expirationTime); + else if (workInProgressRootExitStatus === RootSuspendedWithDelay) + if (workInProgressRootHasPendingPing) + prepareFreshStack(root$jscomp$0, expirationTime); + else { + var lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + } if (null !== workInProgress) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + lastPendingTime = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; null === prevDispatcher && (prevDispatcher = ContextOnlyDispatcher); ReactCurrentDispatcher.current = ContextOnlyDispatcher; @@ -5151,8 +5712,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) return ( - (workPhase = prevWorkPhase), - resetContextDependences(), + (executionContext = lastPendingTime), + resetContextDependencies(), (ReactCurrentDispatcher.current = prevDispatcher), (tracing.__interactionsRef.current = prevInteractions), renderRoot.bind(null, root$jscomp$0, currentTime) @@ -5169,14 +5730,14 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = performUnitOfWork(workInProgress); break; } catch (thrownValue) { - resetContextDependences(); + resetContextDependencies(); resetHooks(); currentTime = workInProgress; if (null === currentTime || null === currentTime.return) throw (prepareFreshStack(root$jscomp$0, expirationTime), - (workPhase = prevWorkPhase), + (executionContext = lastPendingTime), thrownValue); - currentTime.mode & 4 && + currentTime.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(currentTime, !0); a: { var root = root$jscomp$0, @@ -5191,29 +5752,41 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; + var thenable = value, + hasInvisibleParentBoundary = + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext); value = returnFiber; do { - if ( - 13 === value.tag && - (void 0 === value.memoizedProps.fallback - ? 0 - : null === value.memoizedState) - ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === value.tag)) + null !== value.memoizedState + ? (JSCompiler_temp = !1) + : ((JSCompiler_temp = value.memoizedProps), + (JSCompiler_temp = + void 0 === JSCompiler_temp.fallback + ? !1 + : !0 !== JSCompiler_temp.unstable_avoidThisFallback + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0)); + if (JSCompiler_temp) { returnFiber = value.updateQueue; null === returnFiber ? ((returnFiber = new Set()), returnFiber.add(thenable), (value.updateQueue = returnFiber)) : returnFiber.add(thenable); - if (0 === (value.mode & 1)) { + if (0 === (value.mode & 2)) { value.effectTag |= 64; sourceFiber.effectTag &= -1957; 1 === sourceFiber.tag && (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((renderExpirationTime$jscomp$0 = createUpdate( - 1073741823 + 1073741823, + null )), (renderExpirationTime$jscomp$0.tag = 2), enqueueUpdate( @@ -5225,15 +5798,15 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { } sourceFiber = root; root = renderExpirationTime$jscomp$0; - var pingCache = sourceFiber.pingCache; - null === pingCache - ? ((pingCache = sourceFiber.pingCache = new PossiblyWeakMap()), + hasInvisibleParentBoundary = sourceFiber.pingCache; + null === hasInvisibleParentBoundary + ? ((hasInvisibleParentBoundary = sourceFiber.pingCache = new PossiblyWeakMap()), (returnFiber = new Set()), - pingCache.set(thenable, returnFiber)) - : ((returnFiber = pingCache.get(thenable)), + hasInvisibleParentBoundary.set(thenable, returnFiber)) + : ((returnFiber = hasInvisibleParentBoundary.get(thenable)), void 0 === returnFiber && ((returnFiber = new Set()), - pingCache.set(thenable, returnFiber))); + hasInvisibleParentBoundary.set(thenable, returnFiber))); returnFiber.has(root) || (returnFiber.add(root), (sourceFiber = pingSuspendedRoot.bind( @@ -5256,11 +5829,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { getStackByFiberInDevAndProd(sourceFiber) ); } - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootErrored; + workInProgressRootExitStatus !== RootCompleted && + (workInProgressRootExitStatus = RootErrored); value = createCapturedValue(value, sourceFiber); sourceFiber = returnFiber; do { @@ -5312,80 +5882,148 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = completeUnitOfWork(currentTime); } while (1); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = lastPendingTime; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; tracing.__interactionsRef.current = prevInteractions; if (null !== workInProgress) return renderRoot.bind(null, root$jscomp$0, expirationTime); } + root$jscomp$0.finishedWork = root$jscomp$0.current.alternate; + root$jscomp$0.finishedExpirationTime = expirationTime; if (resolveLocksOnRoot(root$jscomp$0, expirationTime)) return null; workInProgressRoot = null; switch (workInProgressRootExitStatus) { case RootIncomplete: - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); case RootErrored: return ( - (prevWorkPhase = root$jscomp$0.lastPendingTime), - root$jscomp$0.lastPendingTime < expirationTime - ? renderRoot.bind(null, root$jscomp$0, prevWorkPhase) + (lastPendingTime = root$jscomp$0.lastPendingTime), + lastPendingTime < expirationTime + ? renderRoot.bind(null, root$jscomp$0, lastPendingTime) : isSync - ? commitRoot.bind(null, root$jscomp$0, expirationTime) + ? commitRoot.bind(null, root$jscomp$0) : (prepareFreshStack(root$jscomp$0, expirationTime), - scheduleCallback( - 99, + scheduleSyncCallback( renderRoot.bind(null, root$jscomp$0, expirationTime) ), null) ); case RootSuspended: + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + !isSync && + ((isSync = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < isSync) + ) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); + lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + isSync + ); + return null; + } + return commitRoot.bind(null, root$jscomp$0); + case RootSuspendedWithDelay: if (!isSync) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); isSync = root$jscomp$0.lastPendingTime; - if (root$jscomp$0.lastPendingTime < expirationTime) + if (isSync < expirationTime) return renderRoot.bind(null, root$jscomp$0, isSync); - if ( - 1073741823 !== workInProgressRootMostRecentEventTime && - ((prevWorkPhase = - 10 * (1073741822 - workInProgressRootMostRecentEventTime) - 5e3), - (isSync = now()), - (prevWorkPhase = isSync - prevWorkPhase), - (prevWorkPhase = - (120 > prevWorkPhase - ? 120 - : 480 > prevWorkPhase - ? 480 - : 1080 > prevWorkPhase - ? 1080 - : 1920 > prevWorkPhase - ? 1920 - : 3e3 > prevWorkPhase - ? 3e3 - : 4320 > prevWorkPhase - ? 4320 - : 1960 * ceil(prevWorkPhase / 1960)) - prevWorkPhase), - (isSync = 10 * (1073741822 - expirationTime) - isSync), - isSync < prevWorkPhase && (prevWorkPhase = isSync), - (isSync = prevWorkPhase), - 10 < isSync) - ) + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (isSync = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (isSync = 0) + : ((isSync = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (lastPendingTime = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - lastPendingTime), + (isSync = lastPendingTime - isSync), + 0 > isSync && (isSync = 0), + (isSync = + (120 > isSync + ? 120 + : 480 > isSync + ? 480 + : 1080 > isSync + ? 1080 + : 1920 > isSync + ? 1920 + : 3e3 > isSync + ? 3e3 + : 4320 > isSync + ? 4320 + : 1960 * ceil(isSync / 1960)) - isSync), + expirationTime < isSync && (isSync = expirationTime)); + if (10 < isSync) return ( (root$jscomp$0.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root$jscomp$0, expirationTime), + commitRoot.bind(null, root$jscomp$0), isSync )), null ); } - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return commitRoot.bind(null, root$jscomp$0); case RootCompleted: - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return !isSync && + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig && + ((lastPendingTime = workInProgressRootLatestProcessedExpirationTime), + (prevDispatcher = workInProgressRootCanSuspendUsingConfig), + (expirationTime = prevDispatcher.busyMinDurationMs | 0), + 0 >= expirationTime + ? (expirationTime = 0) + : ((isSync = prevDispatcher.busyDelayMs | 0), + (lastPendingTime = + now() - + (10 * (1073741821 - lastPendingTime) - + (prevDispatcher.timeoutMs | 0 || 5e3))), + (expirationTime = + lastPendingTime <= isSync + ? 0 + : isSync + expirationTime - lastPendingTime)), + 10 < expirationTime) + ? ((root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + expirationTime + )), + null) + : commitRoot.bind(null, root$jscomp$0); default: - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } } +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 1 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 1 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} function performUnitOfWork(unitOfWork) { var current$$1 = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 4) + 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), @@ -5402,7 +6040,7 @@ function completeUnitOfWork(unitOfWork) { var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 1024)) { - if (0 === (workInProgress.mode & 4)) + if (0 === (workInProgress.mode & 8)) current$$1 = completeWork( current$$1, workInProgress, @@ -5422,7 +6060,7 @@ function completeUnitOfWork(unitOfWork) { fiber = workInProgress; if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; - if (0 !== (fiber.mode & 4)) { + if (0 !== (fiber.mode & 8)) { for ( var actualDuration = fiber.actualDuration, treeBaseDuration = fiber.selfBaseDuration, @@ -5474,7 +6112,7 @@ function completeUnitOfWork(unitOfWork) { (unitOfWork.lastEffect = workInProgress))); } else { current$$1 = unwindWork(workInProgress, renderExpirationTime); - if (0 !== (workInProgress.mode & 4)) { + if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; for ( @@ -5500,8 +6138,8 @@ function completeUnitOfWork(unitOfWork) { (workInProgressRootExitStatus = RootCompleted); return null; } -function commitRoot(root, expirationTime) { - runWithPriority(99, commitRootImpl.bind(null, root, expirationTime)); +function commitRoot(root) { + runWithPriority$1(99, commitRootImpl.bind(null, root)); null !== rootWithPendingPassiveEffects && ((root = getCurrentPriorityLevel()), scheduleCallback(root, function() { @@ -5510,13 +6148,21 @@ function commitRoot(root, expirationTime) { })); return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); - var finishedWork = root.current.alternate; - if (null === finishedWork) - throw ReactError("Should have a work-in-progress root."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); + var finishedWork = root.finishedWork, + expirationTime = root.finishedExpirationTime; + if (null === finishedWork) return null; + root.finishedWork = null; + root.finishedExpirationTime = 0; + if (finishedWork === root.current) + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); root.callbackNode = null; root.callbackExpirationTime = 0; var updateExpirationTimeBeforeCommit = finishedWork.expirationTime, @@ -5530,19 +6176,19 @@ function commitRootImpl(root, expirationTime) { (root.lastPendingTime = updateExpirationTimeBeforeCommit); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); - if (1 < finishedWork.effectTag) - if (null !== finishedWork.lastEffect) { - finishedWork.lastEffect.nextEffect = finishedWork; - var firstEffect = finishedWork.firstEffect; - } else firstEffect = finishedWork; - else firstEffect = finishedWork.firstEffect; - if (null !== firstEffect) { - updateExpirationTimeBeforeCommit = workPhase; - workPhase = CommitPhase; - childExpirationTimeBeforeCommit = tracing.__interactionsRef.current; + 1 < finishedWork.effectTag + ? null !== finishedWork.lastEffect + ? ((finishedWork.lastEffect.nextEffect = finishedWork), + (updateExpirationTimeBeforeCommit = finishedWork.firstEffect)) + : (updateExpirationTimeBeforeCommit = finishedWork) + : (updateExpirationTimeBeforeCommit = finishedWork.firstEffect); + if (null !== updateExpirationTimeBeforeCommit) { + childExpirationTimeBeforeCommit = executionContext; + executionContext |= CommitContext; + var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; ReactCurrentOwner$2.current = null; - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5585,11 +6231,12 @@ function commitRootImpl(root, expirationTime) { case 6: case 4: case 17: - case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5597,13 +6244,13 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); commitTime = now$1(); - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5644,8 +6291,8 @@ function commitRootImpl(root, expirationTime) { if (null !== updateQueue) { var lastEffect = updateQueue.lastEffect; if (null !== lastEffect) { - var firstEffect$jscomp$0 = lastEffect.next; - snapshot = firstEffect$jscomp$0; + var firstEffect = lastEffect.next; + snapshot = firstEffect; do { var destroy = snapshot.destroy; if (void 0 !== destroy) { @@ -5660,7 +6307,7 @@ function commitRootImpl(root, expirationTime) { } } snapshot = snapshot.next; - } while (snapshot !== firstEffect$jscomp$0); + } while (snapshot !== firstEffect); } } break; @@ -5706,24 +6353,26 @@ function commitRootImpl(root, expirationTime) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; null !== alternate && ((alternate.return = null), (alternate.child = null), (alternate.memoizedState = null), - (alternate.updateQueue = null)); + (alternate.updateQueue = null), + (alternate.dependencies = null)); } nextEffect = nextEffect.nextEffect; } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); root.current = finishedWork; - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for ( @@ -5794,7 +6443,9 @@ function commitRootImpl(root, expirationTime) { case 5: if (null === current$$1$jscomp$1 && currentRef.effectTag & 4) throw ReactError( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -5803,26 +6454,27 @@ function commitRootImpl(root, expirationTime) { break; case 12: var onRender = currentRef.memoizedProps.onRender; - onRender( - currentRef.memoizedProps.id, - null === current$$1$jscomp$1 ? "mount" : "update", - currentRef.actualDuration, - currentRef.treeBaseDuration, - currentRef.actualStartTime, - commitTime, - lastEffect.memoizedInteractions - ); + "function" === typeof onRender && + onRender( + currentRef.memoizedProps.id, + null === current$$1$jscomp$1 ? "mount" : "update", + currentRef.actualDuration, + currentRef.treeBaseDuration, + currentRef.actualStartTime, + commitTime, + lastEffect.memoizedInteractions + ); break; case 13: + case 19: case 17: - break; case 20: break; - case 19: - break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5847,32 +6499,51 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); nextEffect = null; - tracing.__interactionsRef.current = childExpirationTimeBeforeCommit; - workPhase = updateExpirationTimeBeforeCommit; + requestPaint(); + tracing.__interactionsRef.current = prevInteractions; + executionContext = childExpirationTimeBeforeCommit; } else (root.current = finishedWork), (commitTime = now$1()); - rootDoesHavePassiveEffects - ? ((rootDoesHavePassiveEffects = !1), + if ((effectTag$jscomp$0 = rootDoesHavePassiveEffects)) + (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsExpirationTime = expirationTime)) - : finishPendingInteractions(root, expirationTime); - expirationTime = root.firstPendingTime; - 0 !== expirationTime - ? ((effectTag$jscomp$0 = requestCurrentTime()), - (effectTag$jscomp$0 = inferPriorityFromExpirationTime( - effectTag$jscomp$0, - expirationTime - )), - scheduleCallbackForRoot(root, effectTag$jscomp$0, expirationTime)) - : (legacyErrorBoundariesThatAlreadyFailed = null); + (pendingPassiveEffectsExpirationTime = expirationTime); + else + for (nextEffect = updateExpirationTimeBeforeCommit; null !== nextEffect; ) + (current$$1$jscomp$1 = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + (nextEffect = current$$1$jscomp$1); + current$$1$jscomp$1 = root.firstPendingTime; + if (0 !== current$$1$jscomp$1) { + instance$jscomp$1 = requestCurrentTime(); + instance$jscomp$1 = inferPriorityFromExpirationTime( + instance$jscomp$1, + current$$1$jscomp$1 + ); + if (null !== spawnedWorkDuringRender) + for ( + prevProps$jscomp$0 = spawnedWorkDuringRender, + spawnedWorkDuringRender = null, + updateQueue$jscomp$0 = 0; + updateQueue$jscomp$0 < prevProps$jscomp$0.length; + updateQueue$jscomp$0++ + ) + scheduleInteractions( + root, + prevProps$jscomp$0[updateQueue$jscomp$0], + root.memoizedInteractions + ); + scheduleCallbackForRoot(root, instance$jscomp$1, current$$1$jscomp$1); + } else legacyErrorBoundariesThatAlreadyFailed = null; + effectTag$jscomp$0 || finishPendingInteractions(root, expirationTime); "function" === typeof onCommitFiberRoot && - onCommitFiberRoot(finishedWork.stateNode); - 1073741823 === expirationTime + onCommitFiberRoot(finishedWork.stateNode, expirationTime); + 1073741823 === current$$1$jscomp$1 ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -5882,8 +6553,8 @@ function commitRootImpl(root, expirationTime) { (root = firstUncaughtError), (firstUncaughtError = null), root); - if (workPhase === LegacyUnbatchedPhase) return null; - flushImmediateQueue(); + if ((executionContext & LegacyUnbatchedContext) !== NoContext) return null; + flushSyncCallbackQueue(); return null; } function flushPassiveEffects() { @@ -5894,25 +6565,36 @@ function flushPassiveEffects() { pendingPassiveEffectsExpirationTime = 0; var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Cannot flush passive effects while already rendering."); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; for (var effect = root.current.firstEffect; null !== effect; ) { try { var finishedWork = effect; - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if (0 !== (finishedWork.effectTag & 512)) + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork), + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + } } catch (error) { - if (null === effect) throw ReactError("Should be working on an effect."); + if (null === effect) + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(effect, error); } - effect = effect.nextEffect; + finishedWork = effect.nextEffect; + effect.nextEffect = null; + effect = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); return !0; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -5953,11 +6635,18 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); workInProgressRoot === root && renderExpirationTime === suspendedTime - ? prepareFreshStack(root, renderExpirationTime) + ? workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ? prepareFreshStack(root, renderExpirationTime) + : (workInProgressRootHasPendingPing = !0) : root.lastPendingTime < suspendedTime || ((thenable = root.pingTime), (0 !== thenable && thenable < suspendedTime) || ((root.pingTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), (thenable = requestCurrentTime()), (thenable = inferPriorityFromExpirationTime(thenable, suspendedTime)), scheduleCallbackForRoot(root, thenable, suspendedTime))); @@ -5966,7 +6655,7 @@ function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(thenable); retryCache = requestCurrentTime(); - thenable = computeExpirationForFiber(retryCache, boundaryFiber); + thenable = computeExpirationForFiber(retryCache, boundaryFiber, null); retryCache = inferPriorityFromExpirationTime(retryCache, thenable); boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && @@ -6019,6 +6708,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, renderExpirationTime ); + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( current$$1, workInProgress, @@ -6026,6 +6720,39 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); return null !== workInProgress ? workInProgress.sibling : null; } + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); + break; + case 19: + updateExpirationTime = 0 !== (current$$1.effectTag & 64); + if (workInProgress.childExpirationTime < renderExpirationTime) + return ( + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ), + updateExpirationTime && (workInProgress.effectTag |= 64), + null + ); + if (updateExpirationTime) + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + updateExpirationTime = workInProgress.memoizedState; + null !== updateExpirationTime && + ((updateExpirationTime.rendering = null), + (updateExpirationTime.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); } return bailoutOnAlreadyFinishedWork( current$$1, @@ -6161,9 +6888,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { break; default: throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." + Error( + "Element type is invalid. Received a promise that resolves to: " + + context + + ". Lazy element type must resolve to a class or function." + ) ); } return workInProgress; @@ -6204,7 +6933,9 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime = workInProgress.updateQueue; if (null === updateExpirationTime) throw ReactError( - "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." + 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." + ) ); context = workInProgress.memoizedState; context = null !== context ? context.element : null; @@ -6360,16 +7091,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== oldValue; ) { - var list = oldValue.contextDependencies; + var list = oldValue.dependencies; if (null !== list) { getDerivedStateFromProps = oldValue.child; - for (var dependency = list.first; null !== dependency; ) { + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { if ( dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { 1 === oldValue.tag && - ((dependency = createUpdate(renderExpirationTime)), + ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), enqueueUpdate(oldValue, dependency)); oldValue.expirationTime < renderExpirationTime && @@ -6378,22 +7113,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); - dependency = renderExpirationTime; - for (var node = oldValue.return; null !== node; ) { - var alternate = node.alternate; - if (node.childExpirationTime < dependency) - (node.childExpirationTime = dependency), - null !== alternate && - alternate.childExpirationTime < dependency && - (alternate.childExpirationTime = dependency); - else if ( - null !== alternate && - alternate.childExpirationTime < dependency - ) - alternate.childExpirationTime = dependency; - else break; - node = node.return; - } + scheduleWorkOnParentPath( + oldValue.return, + renderExpirationTime + ); list.expirationTime < renderExpirationTime && (list.expirationTime = renderExpirationTime); break; @@ -6520,13 +7243,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ) ); + case 19: + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); }; -function schedulePendingInteraction(root, expirationTime) { - var interactions = tracing.__interactionsRef.current; +function scheduleInteractions(root, expirationTime, interactions) { if (0 < interactions.size) { var pendingInteractionMap = root.pendingInteractionMap, pendingInteractions = pendingInteractionMap.get(expirationTime); @@ -6547,7 +7277,7 @@ function schedulePendingInteraction(root, expirationTime) { ); } } -function startWorkOnPendingInteraction(root, expirationTime) { +function startWorkOnPendingInteractions(root, expirationTime) { var interactions = new Set(); root.pendingInteractionMap.forEach(function( scheduledInteractions, @@ -6611,6 +7341,34 @@ function finishPendingInteractions(root, committedExpirationTime) { }); } } +var onCommitFiberRoot = null, + onCommitFiberUnmount = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled || !hook.supportsFiber) return !0; + try { + var rendererID = hook.inject(internals); + onCommitFiberRoot = function(root, expirationTime) { + try { + var didError = 64 === (root.current.effectTag & 64), + currentTime = requestCurrentTime(), + priorityLevel = inferPriorityFromExpirationTime( + currentTime, + expirationTime + ); + hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); + } catch (err) {} + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) {} + }; + } catch (err) {} + return !0; +} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -6618,7 +7376,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.index = 0; this.ref = null; this.pendingProps = pendingProps; - this.contextDependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; + this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; this.effectTag = 0; this.lastEffect = this.firstEffect = this.nextEffect = null; @@ -6672,7 +7430,16 @@ function createWorkInProgress(current, pendingProps) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + pendingProps = current.dependencies; + workInProgress.dependencies = + null === pendingProps + ? null + : { + expirationTime: pendingProps.expirationTime, + firstContext: pendingProps.firstContext, + listeners: pendingProps.listeners, + responders: pendingProps.responders + }; workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; @@ -6702,12 +7469,16 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 3, expirationTime, key); + fiberTag = 8; + mode |= 7; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 2, expirationTime, key); + fiberTag = 8; + mode |= 1; + break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -6716,8 +7487,15 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.elementType = REACT_SUSPENSE_TYPE), (type.type = REACT_SUSPENSE_TYPE), + (type.elementType = REACT_SUSPENSE_TYPE), + (type.expirationTime = expirationTime), + type + ); + case REACT_SUSPENSE_LIST_TYPE: + return ( + (type = createFiber(19, pendingProps, key, mode)), + (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type ); @@ -6742,9 +7520,11 @@ function createFiberFromTypeAndProps( break a; } throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (null == type ? type : typeof type) + - "." + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (null == type ? type : typeof type) + + "." + ) ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -6758,14 +7538,6 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { elements.expirationTime = expirationTime; return elements; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - pendingProps = createFiber(8, pendingProps, key, mode); - mode = 0 === (mode & 1) ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; - pendingProps.elementType = mode; - pendingProps.type = mode; - pendingProps.expirationTime = expirationTime; - return pendingProps; -} function createFiberFromText(content, mode, expirationTime) { content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; @@ -6786,11 +7558,12 @@ function createFiberFromPortal(portal, mode, expirationTime) { }; return mode; } -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pingCache = this.pendingChildren = null; - this.pendingCommitExpirationTime = 0; + this.finishedExpirationTime = 0; this.finishedWork = null; this.timeoutHandle = -1; this.pendingContext = this.context = null; @@ -6805,10 +7578,12 @@ function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { if ("function" === typeof component.render) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } component = findCurrentHostFiber(fiber); @@ -6816,8 +7591,13 @@ function findHostInstance(component) { } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current, - currentTime = requestCurrentTime(); - current$$1 = computeExpirationForFiber(currentTime, current$$1); + currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + current$$1 = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); currentTime = container.current; a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; @@ -6827,7 +7607,9 @@ function updateContainer(element, container, parentComponent, callback) { 1 !== parentComponent.tag ) throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + 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 parentContext = parentComponent; do { @@ -6846,7 +7628,9 @@ function updateContainer(element, container, parentComponent, callback) { parentContext = parentContext.return; } while (null !== parentContext); throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (1 === parentComponent.tag) { @@ -6866,12 +7650,11 @@ function updateContainer(element, container, parentComponent, callback) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(current$$1); - callback.payload = { element: element }; + suspenseConfig = createUpdate(current$$1, suspenseConfig); + suspenseConfig.payload = { element: element }; container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - flushPassiveEffects(); - enqueueUpdate(currentTime, callback); + null !== container && (suspenseConfig.callback = container); + enqueueUpdate(currentTime, suspenseConfig); scheduleUpdateOnFiber(currentTime, current$$1); return current$$1; } @@ -6886,7 +7669,7 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } -function _inherits(subClass, superClass) { +function _inherits$1(subClass, superClass) { if ("function" !== typeof superClass && null !== superClass) throw new TypeError( "Super expression must either be null or a function, not " + @@ -6908,9 +7691,10 @@ function _inherits(subClass, superClass) { var getInspectorDataForViewTag = void 0; getInspectorDataForViewTag = function() { throw ReactError( - "getInspectorDataForViewTag() is not available in production" + Error("getInspectorDataForViewTag() is not available in production") ); }; +var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -6924,19 +7708,19 @@ function findNodeHandle(componentOrHandle) { ? componentOrHandle.canonical._nativeTag : componentOrHandle._nativeTag; } -_batchedUpdatesImpl = function(fn, a) { - if (0 !== workPhase) return fn(a); - workPhase = 1; +batchedUpdatesImpl = function(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= 1; try { return fn(a); } finally { - (workPhase = 0), flushImmediateQueue(); + (executionContext = prevExecutionContext), + executionContext === NoContext && flushSyncCallbackQueue(); } }; -_flushInteractiveUpdatesImpl = function() { - workPhase !== RenderPhase && - workPhase !== CommitPhase && - flushPendingDiscreteUpdates(); +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); }; var roots = new Map(), ReactFabric = { @@ -6955,7 +7739,7 @@ var roots = new Map(), ? this : call; } - _inherits(ReactNativeComponent, _React$Component); + _inherits$1(ReactNativeComponent, _React$Component); ReactNativeComponent.prototype.blur = function() { ReactNativePrivateInterface.TextInputState.blurTextInput( findNodeHandle(this) @@ -7051,12 +7835,21 @@ var roots = new Map(), })(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, setNativeProps: function() {}, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + null != handle._internalInstanceHandle && + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + }, render: function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = new FiberRootNode(containerTag, !1); + root = new FiberRootNode(containerTag, 0, !1); var uninitializedFiber = 0; - isDevToolsPresent && (uninitializedFiber |= 4); + isDevToolsPresent && (uninitializedFiber |= 8); uninitializedFiber = createFiber(3, null, null, uninitializedFiber); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -7203,7 +7996,8 @@ var roots = new Map(), findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, - setRefreshHandler: null + setRefreshHandler: null, + getCurrentFiber: null }) ); })({ diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 361d39800277e8..e439de16a08195 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -22,12 +22,11 @@ var checkPropTypes = require("prop-types/checkPropTypes"); var Scheduler = require("scheduler"); var tracing = require("scheduler/tracing"); -// Do not require this module directly! Use a normal error constructor with +// Do not require this module directly! Use normal `invariant` calls with // template literal strings. The messages will be converted to ReactError during // build, and in production they will be minified. -function ReactError(message) { - var error = new Error(message); +function ReactError(error) { error.name = "Invariant Violation"; return error; } @@ -69,9 +68,11 @@ function recomputePluginOrdering() { (function() { if (!(pluginIndex > -1)) { throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); } })(); @@ -81,9 +82,11 @@ function recomputePluginOrdering() { (function() { if (!pluginModule.extractEvents) { throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); } })(); @@ -99,11 +102,13 @@ function recomputePluginOrdering() { ) ) { throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } })(); @@ -123,9 +128,11 @@ function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { (function() { if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ) ); } })(); @@ -166,9 +173,11 @@ function publishRegistrationName(registrationName, pluginModule, eventName) { (function() { if (!!registrationNameModules[registrationName]) { throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); } })(); @@ -229,7 +238,9 @@ function injectEventPluginOrder(injectedEventPluginOrder) { (function() { if (!!eventPluginOrder) { throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); } })(); @@ -262,9 +273,11 @@ function injectEventPluginsByName(injectedNamesToPlugins) { (function() { if (!!namesToPlugins[pluginName]) { throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); } })(); @@ -344,7 +357,9 @@ var invokeGuardedCallbackImpl = function( (function() { if (!(typeof document !== "undefined")) { throw ReactError( - "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." + Error( + "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." + ) ); } })(); @@ -573,7 +588,9 @@ function clearCaughtError() { (function() { { throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -787,7 +804,7 @@ function executeDirectDispatch(event) { var dispatchInstance = event._dispatchInstances; (function() { if (!!Array.isArray(dispatchListener)) { - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); } })(); event.currentTarget = dispatchListener @@ -825,7 +842,9 @@ function accumulateInto(current, next) { (function() { if (!(next != null)) { throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); } })(); @@ -913,7 +932,9 @@ function runEventsInBatch(events) { (function() { if (!!eventQueue) { throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); } })(); @@ -1014,11 +1035,13 @@ function getListener(inst, registrationName) { (function() { if (!(!listener || typeof listener === "function")) { throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); } })(); @@ -1091,8 +1114,8 @@ var SimpleMemoComponent = 15; var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedSuspenseComponent = 18; -var EventComponent = 19; -var EventTarget = 20; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; function getParent(inst) { do { @@ -1614,7 +1637,9 @@ function releasePooledEvent(event) { (function() { if (!(event instanceof EventConstructor)) { throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); } })(); @@ -1726,7 +1751,7 @@ function getTouchIdentifier(_ref) { (function() { if (!(identifier != null)) { - throw ReactError("Touch object is missing identifier."); + throw ReactError(Error("Touch object is missing identifier.")); } })(); { @@ -1766,7 +1791,7 @@ function recordTouchMove(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.error( + console.warn( "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -1787,7 +1812,7 @@ function recordTouchEnd(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.error( + console.warn( "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -1859,7 +1884,9 @@ function accumulate(current, next) { (function() { if (!(next != null)) { throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error( + "accumulate(...): Accumulated items must not be null or undefined." + ) ); } })(); @@ -2483,7 +2510,9 @@ var ReactNativeBridgeEventPlugin = { (function() { if (!(bubbleDispatchConfig || directDispatchConfig)) { throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); } })(); @@ -2530,20 +2559,20 @@ injection.injectEventPluginsByName({ ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin }); -var instanceCache = {}; -var instanceProps = {}; +var instanceCache = new Map(); +var instanceProps = new Map(); function precacheFiberNode(hostInst, tag) { - instanceCache[tag] = hostInst; + instanceCache.set(tag, hostInst); } function uncacheFiberNode(tag) { - delete instanceCache[tag]; - delete instanceProps[tag]; + instanceCache.delete(tag); + instanceProps.delete(tag); } function getInstanceFromTag(tag) { - return instanceCache[tag] || null; + return instanceCache.get(tag) || null; } function getTagFromInstance(inst) { @@ -2553,18 +2582,18 @@ function getTagFromInstance(inst) { } (function() { if (!tag) { - throw ReactError("All native instances should have a tag."); + throw ReactError(Error("All native instances should have a tag.")); } })(); return tag; } function getFiberCurrentPropsFromNode$1(stateNode) { - return instanceProps[stateNode._nativeTag] || null; + return instanceProps.get(stateNode._nativeTag) || null; } function updateFiberProps(tag, props) { - instanceProps[tag] = props; + instanceProps.set(tag, props); } // Use to restore controlled state after a change event has fired. @@ -2584,7 +2613,9 @@ function restoreStateOfTarget(target) { (function() { if (!(typeof restoreImpl === "function")) { throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -2613,6 +2644,31 @@ function restoreStateIfNeeded() { } } +// Re-export dynamic flags from the fbsource version. +var _require = require("../shims/ReactFeatureFlags"); + +var debugRenderPhaseSideEffects = _require.debugRenderPhaseSideEffects; + +var enableUserTimingAPI = true; +var enableProfilerTimer = true; +var enableSchedulerTracing = true; +var enableSuspenseServerRenderer = false; + +var debugRenderPhaseSideEffectsForStrictMode = true; + +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; +var warnAboutDeprecatedLifecycles = true; +var warnAboutDeprecatedSetNativeProps = true; +var enableFlareAPI = false; +var enableFundamentalAPI = false; + +var revertPassiveEffectsChange = false; + +var enableSuspenseCallback = false; +var warnAboutDefaultPropsOnFunctionComponents = false; + +// Only used in www builds. + // Used as a way to call batchedUpdates when we don't have a reference to // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when @@ -2620,45 +2676,50 @@ function restoreStateIfNeeded() { // scheduled work and instead do synchronous work. // Defaults -var _batchedUpdatesImpl = function(fn, bookkeeping) { +var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; -var _flushInteractiveUpdatesImpl = function() {}; +var flushDiscreteUpdatesImpl = function() {}; +var isInsideEventHandler = false; + +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} -var isBatching = false; function batchedUpdates(fn, bookkeeping) { - if (isBatching) { + if (isInsideEventHandler) { // If we are currently inside another batch, we need to wait until it // fully completes before restoring state. return fn(bookkeeping); } - isBatching = true; + isInsideEventHandler = true; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - // Here we wait until all updates have propagated, which is important - // when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - // Then we restore state of any controlled component. - isBatching = false; - var controlledComponentsHavePendingUpdates = needsStateRestore(); - if (controlledComponentsHavePendingUpdates) { - // If a controlled event was fired, we may need to restore the state of - // the DOM node back to the controlled value. This is necessary when React - // bails out of the update without touching the DOM. - _flushInteractiveUpdatesImpl(); - restoreStateIfNeeded(); - } + isInsideEventHandler = false; + finishEventHandler(); } } function setBatchingImplementation( - batchedUpdatesImpl, - interactiveUpdatesImpl, - flushInteractiveUpdatesImpl + _batchedUpdatesImpl, + _discreteUpdatesImpl, + _flushDiscreteUpdatesImpl, + _batchedEventUpdatesImpl ) { - _batchedUpdatesImpl = batchedUpdatesImpl; - _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; + batchedUpdatesImpl = _batchedUpdatesImpl; + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; } /** @@ -2878,6 +2939,11 @@ if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { current: null }; } +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. @@ -2892,6 +2958,8 @@ var REACT_STRICT_MODE_TYPE = hasSymbol var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; +// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") @@ -2900,19 +2968,15 @@ var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 0xead0; var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -var REACT_EVENT_COMPONENT_TYPE = hasSymbol - ? Symbol.for("react.event_component") +var REACT_FUNDAMENTAL_TYPE = hasSymbol + ? Symbol.for("react.fundamental") : 0xead5; -var REACT_EVENT_TARGET_TYPE = hasSymbol - ? Symbol.for("react.event_target") - : 0xead6; - -// React event targets -var REACT_EVENT_TARGET_TOUCH_HIT = hasSymbol - ? Symbol.for("react.event_target.touch_hit") - : 0xead7; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; @@ -2938,27 +3002,6 @@ function refineResolvedLazyComponent(lazyComponent) { return lazyComponent._status === Resolved ? lazyComponent._result : null; } -// Re-export dynamic flags from the fbsource version. -var _require = require("../shims/ReactFeatureFlags"); - -var debugRenderPhaseSideEffects = _require.debugRenderPhaseSideEffects; - -var enableUserTimingAPI = true; -var enableProfilerTimer = true; -var enableSchedulerTracing = true; -var enableSuspenseServerRenderer = false; - -var debugRenderPhaseSideEffectsForStrictMode = true; - -var disableYielding = false; - -var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; -var warnAboutDeprecatedLifecycles = true; -var warnAboutDeprecatedSetNativeProps = true; -var enableEventAPI = false; - -// Only used in www builds. - function getWrappedName(outerType, innerType, wrapperName) { var functionName = innerType.displayName || innerType.name || ""; return ( @@ -2988,8 +3031,6 @@ function getComponentName(type) { return type; } switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -3000,6 +3041,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if (typeof type === "object") { switch (type.$$typeof) { @@ -3019,28 +3062,6 @@ function getComponentName(type) { } break; } - case REACT_EVENT_COMPONENT_TYPE: { - if (enableEventAPI) { - var eventComponent = type; - var displayName = eventComponent.displayName; - if (displayName !== undefined) { - return displayName; - } - } - break; - } - case REACT_EVENT_TARGET_TYPE: { - if (enableEventAPI) { - var eventTarget = type; - if (eventTarget.type === REACT_EVENT_TARGET_TOUCH_HIT) { - return "TouchHitTarget"; - } - var _displayName = eventTarget.displayName; - if (_displayName !== undefined) { - return _displayName; - } - } - } } } return null; @@ -3141,7 +3162,7 @@ function isMounted(component) { function assertIsMounted(fiber) { (function() { if (!(isFiberMountedImpl(fiber) === MOUNTED)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } })(); } @@ -3153,7 +3174,9 @@ function findCurrentFiberUsingSlowPath(fiber) { var state = isFiberMountedImpl(fiber); (function() { if (!(state !== UNMOUNTED)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); if (state === MOUNTING) { @@ -3209,7 +3232,9 @@ function findCurrentFiberUsingSlowPath(fiber) { // way this could possibly happen is if this was unmounted, if at all. (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } @@ -3265,7 +3290,9 @@ function findCurrentFiberUsingSlowPath(fiber) { (function() { if (!didFindChild) { throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } })(); @@ -3275,7 +3302,9 @@ function findCurrentFiberUsingSlowPath(fiber) { (function() { if (!(a.alternate === b)) { throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -3284,7 +3313,7 @@ function findCurrentFiberUsingSlowPath(fiber) { // unmounted. (function() { if (!(a.tag === HostRoot)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } })(); if (a.stateNode.current === a) { @@ -3957,7 +3986,9 @@ function shim() { (function() { { throw ReactError( - "The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -3966,6 +3997,7 @@ function shim() { // Persistence (when unsupported) var supportsPersistence = false; var cloneInstance = shim; +var cloneFundamentalInstance = shim; var createContainerChildSet = shim; var appendChildToContainerChildSet = shim; var finalizeContainerChildren = shim; @@ -3980,7 +4012,9 @@ function shim$1() { (function() { { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -4099,7 +4133,7 @@ function createTextInstance( (function() { if (!hostContext.isInAParentText) { throw ReactError( - "Text strings must be rendered within a component." + Error("Text strings must be rendered within a component.") ); } })(); @@ -4166,16 +4200,6 @@ function getChildHostContext(parentHostContext, type, rootContainerInstance) { } } -function getChildHostContextForEventComponent(parentHostContext) { - // TODO: add getChildHostContextForEventComponent implementation - return parentHostContext; -} - -function getChildHostContextForEventTarget(parentHostContext, type) { - // TODO: add getChildHostContextForEventTarget implementation - return parentHostContext; -} - function getPublicInstance(instance) { return instance; } @@ -4200,6 +4224,7 @@ function resetAfterCommit(containerInfo) { } var isPrimaryRenderer = true; +var warnsIfNotActing = true; var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; @@ -4340,7 +4365,9 @@ function insertInContainerBefore(parentInstance, child, beforeChild) { // For more info on pros/cons see PR #8560 description. (function() { if (!(typeof parentInstance !== "number")) { - throw ReactError("Container does not support insertBefore operation"); + throw ReactError( + Error("Container does not support insertBefore operation") + ); } })(); } @@ -4413,32 +4440,38 @@ function unhideTextInstance(textInstance, text) { throw new Error("Not yet implemented."); } -function mountEventComponent(eventComponentInstance) { +function mountResponderInstance( + responder, + responderInstance, + props, + state, + instance, + rootContainerInstance +) { + throw new Error("Not yet implemented."); +} + +function unmountResponderInstance(responderInstance) { throw new Error("Not yet implemented."); } -function updateEventComponent(eventComponentInstance) { +function getFundamentalComponentInstance(fundamentalInstance) { throw new Error("Not yet implemented."); } -function unmountEventComponent(eventComponentInstance) { +function mountFundamentalComponent(fundamentalInstance) { throw new Error("Not yet implemented."); } -function getEventTargetChildElement(type, props) { +function shouldUpdateFundamentalComponent(fundamentalInstance) { throw new Error("Not yet implemented."); } -function handleEventTarget( - type, - props, - rootContainerInstance, - internalInstanceHandle -) { +function updateFundamentalComponent(fundamentalInstance) { throw new Error("Not yet implemented."); } -function commitEventTarget(type, props, instance, parentInstance) { +function unmountFundamentalComponent(fundamentalInstance) { throw new Error("Not yet implemented."); } @@ -5172,7 +5205,9 @@ function pushTopLevelContextObject(fiber, context, didChange) { (function() { if (!(contextStackCursor.current === emptyContextObject)) { throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -5220,10 +5255,12 @@ function processChildContext(fiber, type, parentContext) { (function() { if (!(contextKey in childContextTypes)) { throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); } })(); @@ -5274,7 +5311,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { (function() { if (!instance) { throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -5309,7 +5348,9 @@ function findCurrentUnmaskedContext(fiber) { (function() { if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -5332,94 +5373,17 @@ function findCurrentUnmaskedContext(fiber) { (function() { { throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); } -var onCommitFiberRoot = null; -var onCommitFiberUnmount = null; -var hasLoggedError = false; - -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); - } - } - }; -} - -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; - -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; - } - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - 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) { - { - warningWithoutStack$1( - false, - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://fb.me/react-devtools" - ); - } - // DevTools exists, even though it doesn't support Fiber. - return true; - } - try { - var rendererID = hook.inject(internals); - // We have successfully injected, so now it is safe to set up hooks. - onCommitFiberRoot = catchErrors(function(root) { - var didError = (root.current.effectTag & DidCapture) === DidCapture; - hook.onCommitFiberRoot(rendererID, root, undefined, didError); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); - } - } - // DevTools exists - return true; -} - -function onCommitRoot(root) { - if (typeof onCommitFiberRoot === "function") { - onCommitFiberRoot(root); - } -} - -function onCommitUnmount(fiber) { - if (typeof onCommitFiberUnmount === "function") { - onCommitFiberUnmount(fiber); - } -} +var LegacyRoot = 0; +var BatchedRoot = 1; +var ConcurrentRoot = 2; /** * Similar to invariant but only logs a warning if the condition is not met. @@ -5464,6 +5428,7 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority; var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback; var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback; var Scheduler_shouldYield = Scheduler.unstable_shouldYield; +var Scheduler_requestPaint = Scheduler.unstable_requestPaint; var Scheduler_now = Scheduler.unstable_now; var Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel; @@ -5485,7 +5450,9 @@ if (enableSchedulerTracing) { ) ) { throw ReactError( - "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 http://fb.me/react-profiling" + 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 http://fb.me/react-profiling" + ) ); } })(); @@ -5503,15 +5470,14 @@ var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. -var shouldYield = disableYielding - ? function() { - return false; - } // Never yield when `disableYielding` is on - : Scheduler_shouldYield; +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 immediateQueue = null; +var syncQueue = null; var immediateQueueCallbackNode = null; -var isFlushingImmediate = false; +var isFlushingSyncQueue = false; var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. @@ -5543,7 +5509,7 @@ function getCurrentPriorityLevel() { default: (function() { { - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } })(); } @@ -5564,7 +5530,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { default: (function() { { - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } })(); } @@ -5576,76 +5542,82 @@ function runWithPriority(reactPriorityLevel, fn) { } function scheduleCallback(reactPriorityLevel, callback, options) { - if (reactPriorityLevel === ImmediatePriority) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushImmediateQueue`. - if (immediateQueue === null) { - immediateQueue = [callback]; - // Flush the queue in the next tick, at the earliest. - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ); - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - immediateQueue.push(callback); - } - return fakeCallbackNode; - } - // Otherwise pass through to Scheduler. 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 flushImmediateQueue() { +function flushSyncCallbackQueue() { if (immediateQueueCallbackNode !== null) { Scheduler_cancelCallback(immediateQueueCallbackNode); } - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && immediateQueue !== null) { +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. - isFlushingImmediate = true; + isFlushingSyncQueue = true; var i = 0; try { var _isSync = true; - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do { - callback = callback(_isSync); - } while (callback !== null); - } - immediateQueue = null; + var queue = syncQueue; + runWithPriority(ImmediatePriority, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do { + callback = callback(_isSync); + } while (callback !== null); + } + }); + syncQueue = null; } catch (error) { // If something throws, leave the remaining callbacks on the queue. - if (immediateQueue !== null) { - immediateQueue = immediateQueue.slice(i + 1); + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); } // Resume flushing in the next tick Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ); throw error; } finally { - isFlushingImmediate = false; + isFlushingSyncQueue = false; } } } -var NoContext = 0; -var ConcurrentMode = 1; -var StrictMode = 2; -var ProfileMode = 4; +var NoMode = 0; +var StrictMode = 1; +// TODO: Remove BatchedMode and ConcurrentMode by reading from the root +// tag instead +var BatchedMode = 2; +var ConcurrentMode = 4; +var ProfileMode = 8; // Max 31 bit integer. The max integer size in V8 for 32-bit systems. // Math.pow(2, 30) - 1 @@ -5655,9 +5627,10 @@ var MAX_SIGNED_31_BIT_INT = 1073741823; var NoWork = 0; var Never = 1; var Sync = MAX_SIGNED_31_BIT_INT; +var Batched = Sync - 1; var UNIT_SIZE = 10; -var MAGIC_NUMBER_OFFSET = MAX_SIGNED_31_BIT_INT - 1; +var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms. function msToExpirationTime(ms) { @@ -5696,10 +5669,13 @@ function computeAsyncExpiration(currentTime) { ); } -// Same as computeAsyncExpiration but without the bucketing logic. This is -// used to compute timestamps instead of actual expiration times. -function computeAsyncExpirationNoBucket(currentTime) { - return currentTime - LOW_PRIORITY_EXPIRATION / UNIT_SIZE; +function computeSuspenseExpiration(currentTime, timeoutMs) { + // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time? + return computeExpirationBucket( + currentTime, + timeoutMs, + LOW_PRIORITY_BATCH_SIZE + ); } // We intentionally set a higher expiration time for interactive updates in @@ -5871,95 +5847,14 @@ var lowPriorityWarning = function() {}; var lowPriorityWarning$1 = lowPriorityWarning; var ReactStrictModeWarnings = { - discardPendingWarnings: function() {}, - flushPendingDeprecationWarnings: function() {}, - flushPendingUnsafeLifecycleWarnings: function() {}, - recordDeprecationWarnings: function(fiber, instance) {}, recordUnsafeLifecycleWarnings: function(fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function() {}, recordLegacyContextWarning: function(fiber, instance) {}, - flushLegacyContextWarning: function() {} + flushLegacyContextWarning: function() {}, + discardPendingWarnings: function() {} }; { - var LIFECYCLE_SUGGESTIONS = { - UNSAFE_componentWillMount: "componentDidMount", - UNSAFE_componentWillReceiveProps: "static getDerivedStateFromProps", - UNSAFE_componentWillUpdate: "componentDidUpdate" - }; - - var pendingComponentWillMountWarnings = []; - var pendingComponentWillReceivePropsWarnings = []; - var pendingComponentWillUpdateWarnings = []; - var pendingUnsafeLifecycleWarnings = new Map(); - var pendingLegacyContextWarning = new Map(); - - // Tracks components we have already warned about. - var didWarnAboutDeprecatedLifecycles = new Set(); - var didWarnAboutUnsafeLifecycles = new Set(); - var didWarnAboutLegacyContext = new Set(); - - var setToSortedString = function(set) { - var array = []; - set.forEach(function(value) { - array.push(value); - }); - return array.sort().join(", "); - }; - - ReactStrictModeWarnings.discardPendingWarnings = function() { - pendingComponentWillMountWarnings = []; - pendingComponentWillReceivePropsWarnings = []; - pendingComponentWillUpdateWarnings = []; - pendingUnsafeLifecycleWarnings = new Map(); - pendingLegacyContextWarning = new Map(); - }; - - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { - pendingUnsafeLifecycleWarnings.forEach(function( - lifecycleWarningsMap, - strictRoot - ) { - var lifecyclesWarningMessages = []; - - Object.keys(lifecycleWarningsMap).forEach(function(lifecycle) { - var lifecycleWarnings = lifecycleWarningsMap[lifecycle]; - if (lifecycleWarnings.length > 0) { - var componentNames = new Set(); - lifecycleWarnings.forEach(function(fiber) { - componentNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - - var formatted = lifecycle.replace("UNSAFE_", ""); - var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle]; - var sortedComponentNames = setToSortedString(componentNames); - - lifecyclesWarningMessages.push( - formatted + - ": Please update the following components to use " + - (suggestion + " instead: " + sortedComponentNames) - ); - } - }); - - if (lifecyclesWarningMessages.length > 0) { - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - - warningWithoutStack$1( - false, - "Unsafe lifecycle methods were found within a strict-mode tree:%s" + - "\n\n%s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-strict-mode-warnings", - strictRootComponentStack, - lifecyclesWarningMessages.join("\n\n") - ); - } - }); - - pendingUnsafeLifecycleWarnings = new Map(); - }; - var findStrictRoot = function(fiber) { var maybeStrictRoot = null; @@ -5974,173 +5869,258 @@ var ReactStrictModeWarnings = { return maybeStrictRoot; }; - ReactStrictModeWarnings.flushPendingDeprecationWarnings = function() { - if (pendingComponentWillMountWarnings.length > 0) { - var uniqueNames = new Set(); - pendingComponentWillMountWarnings.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); - - var sortedNames = setToSortedString(uniqueNames); + var setToSortedString = function(set) { + var array = []; + set.forEach(function(value) { + array.push(value); + }); + return array.sort().join(", "); + }; - lowPriorityWarning$1( - false, - "componentWillMount is deprecated and will be removed in the next major version. " + - "Use componentDidMount instead. As a temporary workaround, " + - "you can rename to UNSAFE_componentWillMount." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - sortedNames - ); - - pendingComponentWillMountWarnings = []; - } - - if (pendingComponentWillReceivePropsWarnings.length > 0) { - var _uniqueNames = new Set(); - pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { - _uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); - - var _sortedNames = setToSortedString(_uniqueNames); - - lowPriorityWarning$1( - false, - "componentWillReceiveProps is deprecated and will be removed in the next major version. " + - "Use static getDerivedStateFromProps instead." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - _sortedNames - ); - - pendingComponentWillReceivePropsWarnings = []; - } - - if (pendingComponentWillUpdateWarnings.length > 0) { - var _uniqueNames2 = new Set(); - pendingComponentWillUpdateWarnings.forEach(function(fiber) { - _uniqueNames2.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); - - var _sortedNames2 = setToSortedString(_uniqueNames2); - - lowPriorityWarning$1( - false, - "componentWillUpdate is deprecated and will be removed in the next major version. " + - "Use componentDidUpdate instead. As a temporary workaround, " + - "you can rename to UNSAFE_componentWillUpdate." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - _sortedNames2 - ); + var pendingComponentWillMountWarnings = []; + var pendingUNSAFE_ComponentWillMountWarnings = []; + var pendingComponentWillReceivePropsWarnings = []; + var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + var pendingComponentWillUpdateWarnings = []; + var pendingUNSAFE_ComponentWillUpdateWarnings = []; - pendingComponentWillUpdateWarnings = []; - } - }; + // Tracks components we have already warned about. + var didWarnAboutUnsafeLifecycles = new Set(); - ReactStrictModeWarnings.recordDeprecationWarnings = function( + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( fiber, instance ) { // Dedup strategy: Warn once per component. - if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) { + if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } - // Don't warn about react-lifecycles-compat polyfilled components. if ( typeof instance.componentWillMount === "function" && + // Don't warn about react-lifecycles-compat polyfilled components. instance.componentWillMount.__suppressDeprecationWarning !== true ) { pendingComponentWillMountWarnings.push(fiber); } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillMount === "function" + ) { + pendingUNSAFE_ComponentWillMountWarnings.push(fiber); + } + if ( typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true ) { pendingComponentWillReceivePropsWarnings.push(fiber); } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); + } + if ( typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true ) { pendingComponentWillUpdateWarnings.push(fiber); } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); + } }; - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( - fiber, - instance - ) { - var strictRoot = findStrictRoot(fiber); - if (strictRoot === null) { + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { + // We do an initial pass to gather component names + var componentWillMountUniqueNames = new Set(); + if (pendingComponentWillMountWarnings.length > 0) { + pendingComponentWillMountWarnings.forEach(function(fiber) { + componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillMountWarnings = []; + } + + var UNSAFE_componentWillMountUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { + pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { + UNSAFE_componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillMountWarnings = []; + } + + var componentWillReceivePropsUniqueNames = new Set(); + if (pendingComponentWillReceivePropsWarnings.length > 0) { + pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { + componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingComponentWillReceivePropsWarnings = []; + } + + var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { + UNSAFE_componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + } + + var componentWillUpdateUniqueNames = new Set(); + if (pendingComponentWillUpdateWarnings.length > 0) { + pendingComponentWillUpdateWarnings.forEach(function(fiber) { + componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingComponentWillUpdateWarnings = []; + } + + var UNSAFE_componentWillUpdateUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { + pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { + UNSAFE_componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingUNSAFE_ComponentWillUpdateWarnings = []; + } + + // Finally, we flush all the warnings + // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' + if (UNSAFE_componentWillMountUniqueNames.size > 0) { + var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); warningWithoutStack$1( false, - "Expected to find a StrictMode component in a strict mode tree. " + - "This error is likely caused by a bug in React. Please file an issue." + "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "\nPlease update the following components: %s", + sortedNames ); - return; } - // Dedup strategy: Warn once per component. - // This is difficult to track any other way since component names - // are often vague and are likely to collide between 3rd party libraries. - // An expand property is probably okay to use here since it's DEV-only, - // and will only be set in the event of serious warnings. - if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { - return; + if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames = setToSortedString( + UNSAFE_componentWillReceivePropsUniqueNames + ); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, " + + "refactor your code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" + + "\nPlease update the following components: %s", + _sortedNames + ); } - var warningsForRoot = void 0; - if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) { - warningsForRoot = { - UNSAFE_componentWillMount: [], - UNSAFE_componentWillReceiveProps: [], - UNSAFE_componentWillUpdate: [] - }; - - pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot); - } else { - warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot); + if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { + var _sortedNames2 = setToSortedString( + UNSAFE_componentWillUpdateUniqueNames + ); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "\nPlease update the following components: %s", + _sortedNames2 + ); } - var unsafeLifecycles = []; - if ( - (typeof instance.componentWillMount === "function" && - instance.componentWillMount.__suppressDeprecationWarning !== true) || - typeof instance.UNSAFE_componentWillMount === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillMount"); - } - if ( - (typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== - true) || - typeof instance.UNSAFE_componentWillReceiveProps === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillReceiveProps"); + if (componentWillMountUniqueNames.size > 0) { + var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); + + lowPriorityWarning$1( + false, + "componentWillMount has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames3 + ); } - if ( - (typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true) || - typeof instance.UNSAFE_componentWillUpdate === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillUpdate"); + + if (componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames4 = setToSortedString( + componentWillReceivePropsUniqueNames + ); + + lowPriorityWarning$1( + false, + "componentWillReceiveProps has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, refactor your " + + "code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" + + "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames4 + ); } - if (unsafeLifecycles.length > 0) { - unsafeLifecycles.forEach(function(lifecycle) { - warningsForRoot[lifecycle].push(fiber); - }); + if (componentWillUpdateUniqueNames.size > 0) { + var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); + + lowPriorityWarning$1( + false, + "componentWillUpdate has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames5 + ); } }; + var pendingLegacyContextWarning = new Map(); + + // Tracks components we have already warned about. + var didWarnAboutLegacyContext = new Set(); + ReactStrictModeWarnings.recordLegacyContextWarning = function( fiber, instance @@ -6189,237 +6169,655 @@ var ReactStrictModeWarnings = { warningWithoutStack$1( false, "Legacy context API has been detected within a strict-mode tree: %s" + + "\n\nThe old API will be supported in all 16.x releases, but applications " + + "using it should migrate to the new version." + "\n\nPlease update the following components: %s" + "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-strict-mode-warnings", + "\nhttps://fb.me/react-legacy-context", strictRootComponentStack, sortedNames ); }); }; + + ReactStrictModeWarnings.discardPendingWarnings = function() { + pendingComponentWillMountWarnings = []; + pendingUNSAFE_ComponentWillMountWarnings = []; + pendingComponentWillReceivePropsWarnings = []; + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + pendingComponentWillUpdateWarnings = []; + pendingUNSAFE_ComponentWillUpdateWarnings = []; + pendingLegacyContextWarning = new Map(); + }; } -function resolveDefaultProps(Component, baseProps) { - if (Component && Component.defaultProps) { - // Resolve default props. Taken from ReactElement - var props = Object.assign({}, baseProps); - var defaultProps = Component.defaultProps; - for (var propName in defaultProps) { - if (props[propName] === undefined) { - props[propName] = defaultProps[propName]; - } - } - return props; +// Resolves type to a family. + +// Used by React Refresh runtime through DevTools Global Hook. + +var resolveFamily = null; +// $FlowFixMe Flow gets confused by a WeakSet feature check below. +var failedBoundaries = null; + +var setRefreshHandler = function(handler) { + { + resolveFamily = handler; } - return baseProps; -} +}; -function readLazyComponentType(lazyComponent) { - var status = lazyComponent._status; - var result = lazyComponent._result; - switch (status) { - case Resolved: { - var Component = result; - return Component; - } - case Rejected: { - var error = result; - throw error; - } - case Pending: { - var thenable = result; - throw thenable; +function resolveFunctionForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; } - default: { - lazyComponent._status = Pending; - var ctor = lazyComponent._ctor; - var _thenable = ctor(); - _thenable.then( - function(moduleObject) { - if (lazyComponent._status === Pending) { - var defaultExport = moduleObject.default; - { - if (defaultExport === undefined) { - warning$1( - false, - "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + - "const MyComponent = lazy(() => import('./MyComponent'))", - moduleObject - ); - } - } - lazyComponent._status = Resolved; - lazyComponent._result = defaultExport; - } - }, - function(error) { - if (lazyComponent._status === Pending) { - lazyComponent._status = Rejected; - lazyComponent._result = error; - } - } - ); - // Handle synchronous thenables. - switch (lazyComponent._status) { - case Resolved: - return lazyComponent._result; - case Rejected: - throw lazyComponent._result; - } - lazyComponent._result = _thenable; - throw _thenable; + var family = resolveFamily(type); + if (family === undefined) { + return type; } + // Use the latest known implementation. + return family.current; } } -var valueCursor = createCursor(null); - -var rendererSigil = void 0; -{ - // Use this to detect multiple renderers using the same context - rendererSigil = {}; +function resolveClassForHotReloading(type) { + // No implementation differences. + return resolveFunctionForHotReloading(type); } -var currentlyRenderingFiber = null; -var lastContextDependency = null; -var lastContextWithAllBitsObserved = null; - -var isDisallowedContextReadInDEV = false; - -function resetContextDependences() { - // This is called right before React yields execution, to ensure `readContext` - // cannot be called outside the render phase. - currentlyRenderingFiber = null; - lastContextDependency = null; - lastContextWithAllBitsObserved = null; +function resolveForwardRefForHotReloading(type) { { - isDisallowedContextReadInDEV = false; + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + var family = resolveFamily(type); + if (family === undefined) { + // Check if we're dealing with a real forwardRef. Don't want to crash early. + if ( + type !== null && + type !== undefined && + typeof type.render === "function" + ) { + // ForwardRef is special because its resolved .type is an object, + // but it's possible that we only have its inner render function in the map. + // If that inner render function is different, we'll build a new forwardRef type. + var currentRender = resolveFunctionForHotReloading(type.render); + if (type.render !== currentRender) { + var syntheticType = { + $$typeof: REACT_FORWARD_REF_TYPE, + render: currentRender + }; + if (type.displayName !== undefined) { + syntheticType.displayName = type.displayName; + } + return syntheticType; + } + } + return type; + } + // Use the latest known implementation. + return family.current; } } -function enterDisallowedContextReadInDEV() { +function isCompatibleFamilyForHotReloading(fiber, element) { { - isDisallowedContextReadInDEV = true; - } -} + if (resolveFamily === null) { + // Hot reloading is disabled. + return false; + } -function exitDisallowedContextReadInDEV() { - { - isDisallowedContextReadInDEV = false; - } -} + var prevType = fiber.elementType; + var nextType = element.type; -function pushProvider(providerFiber, nextValue) { - var context = providerFiber.type._context; + // If we got here, we know types aren't === equal. + var needsCompareFamilies = false; - if (isPrimaryRenderer) { - push(valueCursor, context._currentValue, providerFiber); + var $$typeofNextType = + typeof nextType === "object" && nextType !== null + ? nextType.$$typeof + : null; - context._currentValue = nextValue; - { - !( - context._currentRenderer === undefined || - context._currentRenderer === null || - context._currentRenderer === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; - context._currentRenderer = rendererSigil; + switch (fiber.tag) { + case ClassComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } + break; + } + case FunctionComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + // We don't know the inner type yet. + // We're going to assume that the lazy inner type is stable, + // and so it is sufficient to avoid reconciling it away. + // We're not going to unwrap or actually use the new lazy type. + needsCompareFamilies = true; + } + break; + } + case ForwardRef: { + if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + break; + } + case MemoComponent: + case SimpleMemoComponent: { + if ($$typeofNextType === REACT_MEMO_TYPE) { + // TODO: if it was but can no longer be simple, + // we shouldn't set this. + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + break; + } + default: + return false; } - } else { - push(valueCursor, context._currentValue2, providerFiber); - context._currentValue2 = nextValue; - { - !( - context._currentRenderer2 === undefined || - context._currentRenderer2 === null || - context._currentRenderer2 === rendererSigil - ) - ? warningWithoutStack$1( - false, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ) - : void 0; - context._currentRenderer2 = rendererSigil; + // Check if both types have a family and it's the same one. + if (needsCompareFamilies) { + // Note: memo() and forwardRef() we'll compare outer rather than inner type. + // This means both of them need to be registered to preserve state. + // If we unwrapped and compared the inner types for wrappers instead, + // then we would risk falsely saying two separate memo(Foo) + // calls are equivalent because they wrap the same Foo function. + var prevFamily = resolveFamily(prevType); + if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { + return true; + } } + return false; } } -function popProvider(providerFiber) { - var currentValue = valueCursor.current; - - pop(valueCursor, providerFiber); - - var context = providerFiber.type._context; - if (isPrimaryRenderer) { - context._currentValue = currentValue; - } else { - context._currentValue2 = currentValue; +function markFailedErrorBoundaryForHotReloading(fiber) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + if (typeof WeakSet !== "function") { + return; + } + if (failedBoundaries === null) { + failedBoundaries = new WeakSet(); + } + failedBoundaries.add(fiber); } } -function calculateChangedBits(context, newValue, oldValue) { - if (is(oldValue, newValue)) { - // No change - return 0; - } else { - var changedBits = - typeof context._calculateChangedBits === "function" - ? context._calculateChangedBits(oldValue, newValue) - : MAX_SIGNED_31_BIT_INT; - - { - !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) - ? warning$1( - false, - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ) - : void 0; +var scheduleRefresh = function(root, update) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; } - return changedBits | 0; + var _staleFamilies = update.staleFamilies, + _updatedFamilies = update.updatedFamilies; + + flushPassiveEffects(); + flushSync(function() { + scheduleFibersWithFamiliesRecursively( + root.current, + _updatedFamilies, + _staleFamilies + ); + }); } -} +}; -function scheduleWorkOnParentPath(parent, renderExpirationTime) { - // Update the child expiration time of all the ancestors, including - // the alternates. - var node = parent; - while (node !== null) { - var alternate = node.alternate; - if (node.childExpirationTime < renderExpirationTime) { - node.childExpirationTime = renderExpirationTime; - if ( - alternate !== null && - alternate.childExpirationTime < renderExpirationTime - ) { - alternate.childExpirationTime = renderExpirationTime; - } - } else if ( - alternate !== null && - alternate.childExpirationTime < renderExpirationTime - ) { - alternate.childExpirationTime = renderExpirationTime; - } else { - // Neither alternate was updated, which means the rest of the - // ancestor path already has sufficient priority. - break; +var scheduleRoot = function(root, element) { + { + if (root.context !== emptyContextObject) { + // Super edge case: root has a legacy _renderSubtree context + // but we don't know the parentComponent so we can't pass it. + // Just ignore. We'll delete this with _renderSubtree code path later. + return; } - node = node.return; + flushPassiveEffects(); + updateContainerAtExpirationTime(element, root, null, Sync, null); } -} +}; -function propagateContextChange( - workInProgress, - context, +function scheduleFibersWithFamiliesRecursively( + fiber, + updatedFamilies, + staleFamilies +) { + { + var alternate = fiber.alternate, + child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; + + var candidateType = null; + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + default: + break; + } + + if (resolveFamily === null) { + throw new Error("Expected resolveFamily to be set during hot reload."); + } + + var needsRender = false; + var needsRemount = false; + if (candidateType !== null) { + var family = resolveFamily(candidateType); + if (family !== undefined) { + if (staleFamilies.has(family)) { + needsRemount = true; + } else if (updatedFamilies.has(family)) { + needsRender = true; + } + } + } + if (failedBoundaries !== null) { + if ( + failedBoundaries.has(fiber) || + (alternate !== null && failedBoundaries.has(alternate)) + ) { + needsRemount = true; + } + } + + if (needsRemount) { + fiber._debugNeedsRemount = true; + } + if (needsRemount || needsRender) { + scheduleWork(fiber, Sync); + } + if (child !== null && !needsRemount) { + scheduleFibersWithFamiliesRecursively( + child, + updatedFamilies, + staleFamilies + ); + } + if (sibling !== null) { + scheduleFibersWithFamiliesRecursively( + sibling, + updatedFamilies, + staleFamilies + ); + } + } +} + +var findHostInstancesForRefresh = function(root, families) { + { + var hostInstances = new Set(); + var types = new Set( + families.map(function(family) { + return family.current; + }) + ); + findHostInstancesForMatchingFibersRecursively( + root.current, + types, + hostInstances + ); + return hostInstances; + } +}; + +function findHostInstancesForMatchingFibersRecursively( + fiber, + types, + hostInstances +) { + { + var child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; + + var candidateType = null; + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + default: + break; + } + + var didMatch = false; + if (candidateType !== null) { + if (types.has(candidateType)) { + didMatch = true; + } + } + + if (didMatch) { + // We have a match. This only drills down to the closest host components. + // There's no need to search deeper because for the purpose of giving + // visual feedback, "flashing" outermost parent rectangles is sufficient. + findHostInstancesForFiberShallowly(fiber, hostInstances); + } else { + // If there's no match, maybe there will be one further down in the child tree. + if (child !== null) { + findHostInstancesForMatchingFibersRecursively( + child, + types, + hostInstances + ); + } + } + + if (sibling !== null) { + findHostInstancesForMatchingFibersRecursively( + sibling, + types, + hostInstances + ); + } + } +} + +function findHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var foundHostInstances = findChildHostInstancesForFiberShallowly( + fiber, + hostInstances + ); + if (foundHostInstances) { + return; + } + // If we didn't find any host children, fallback to closest host parent. + var node = fiber; + while (true) { + switch (node.tag) { + case HostComponent: + hostInstances.add(node.stateNode); + return; + case HostPortal: + hostInstances.add(node.stateNode.containerInfo); + return; + case HostRoot: + hostInstances.add(node.stateNode.containerInfo); + return; + } + if (node.return === null) { + throw new Error("Expected to reach root first."); + } + node = node.return; + } + } +} + +function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var node = fiber; + var foundHostInstances = false; + while (true) { + if (node.tag === HostComponent) { + // We got a match. + foundHostInstances = true; + hostInstances.add(node.stateNode); + // There may still be more, so keep searching. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === fiber) { + return foundHostInstances; + } + while (node.sibling === null) { + if (node.return === null || node.return === fiber) { + return foundHostInstances; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + } + return false; +} + +function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + // Resolve default props. Taken from ReactElement + var props = Object.assign({}, baseProps); + var defaultProps = Component.defaultProps; + for (var propName in defaultProps) { + if (props[propName] === undefined) { + props[propName] = defaultProps[propName]; + } + } + return props; + } + return baseProps; +} + +function readLazyComponentType(lazyComponent) { + var status = lazyComponent._status; + var result = lazyComponent._result; + switch (status) { + case Resolved: { + var Component = result; + return Component; + } + case Rejected: { + var error = result; + throw error; + } + case Pending: { + var thenable = result; + throw thenable; + } + default: { + lazyComponent._status = Pending; + var ctor = lazyComponent._ctor; + var _thenable = ctor(); + _thenable.then( + function(moduleObject) { + if (lazyComponent._status === Pending) { + var defaultExport = moduleObject.default; + { + if (defaultExport === undefined) { + warning$1( + false, + "lazy: Expected the result of a dynamic import() call. " + + "Instead received: %s\n\nYour code should look like: \n " + + "const MyComponent = lazy(() => import('./MyComponent'))", + moduleObject + ); + } + } + lazyComponent._status = Resolved; + lazyComponent._result = defaultExport; + } + }, + function(error) { + if (lazyComponent._status === Pending) { + lazyComponent._status = Rejected; + lazyComponent._result = error; + } + } + ); + // Handle synchronous thenables. + switch (lazyComponent._status) { + case Resolved: + return lazyComponent._result; + case Rejected: + throw lazyComponent._result; + } + lazyComponent._result = _thenable; + throw _thenable; + } + } +} + +var valueCursor = createCursor(null); + +var rendererSigil = void 0; +{ + // Use this to detect multiple renderers using the same context + rendererSigil = {}; +} + +var currentlyRenderingFiber = null; +var lastContextDependency = null; +var lastContextWithAllBitsObserved = null; + +var isDisallowedContextReadInDEV = false; + +function resetContextDependencies() { + // This is called right before React yields execution, to ensure `readContext` + // cannot be called outside the render phase. + currentlyRenderingFiber = null; + lastContextDependency = null; + lastContextWithAllBitsObserved = null; + { + isDisallowedContextReadInDEV = false; + } +} + +function enterDisallowedContextReadInDEV() { + { + isDisallowedContextReadInDEV = true; + } +} + +function exitDisallowedContextReadInDEV() { + { + isDisallowedContextReadInDEV = false; + } +} + +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + + if (isPrimaryRenderer) { + push(valueCursor, context._currentValue, providerFiber); + + context._currentValue = nextValue; + { + !( + context._currentRenderer === undefined || + context._currentRenderer === null || + context._currentRenderer === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; + context._currentRenderer = rendererSigil; + } + } else { + push(valueCursor, context._currentValue2, providerFiber); + + context._currentValue2 = nextValue; + { + !( + context._currentRenderer2 === undefined || + context._currentRenderer2 === null || + context._currentRenderer2 === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; + context._currentRenderer2 = rendererSigil; + } + } +} + +function popProvider(providerFiber) { + var currentValue = valueCursor.current; + + pop(valueCursor, providerFiber); + + var context = providerFiber.type._context; + if (isPrimaryRenderer) { + context._currentValue = currentValue; + } else { + context._currentValue2 = currentValue; + } +} + +function calculateChangedBits(context, newValue, oldValue) { + if (is(oldValue, newValue)) { + // No change + return 0; + } else { + var changedBits = + typeof context._calculateChangedBits === "function" + ? context._calculateChangedBits(oldValue, newValue) + : MAX_SIGNED_31_BIT_INT; + + { + !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) + ? warning$1( + false, + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ) + : void 0; + } + return changedBits | 0; + } +} + +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + // Update the child expiration time of all the ancestors, including + // the alternates. + var node = parent; + while (node !== null) { + var alternate = node.alternate; + if (node.childExpirationTime < renderExpirationTime) { + node.childExpirationTime = renderExpirationTime; + if ( + alternate !== null && + alternate.childExpirationTime < renderExpirationTime + ) { + alternate.childExpirationTime = renderExpirationTime; + } + } else if ( + alternate !== null && + alternate.childExpirationTime < renderExpirationTime + ) { + alternate.childExpirationTime = renderExpirationTime; + } else { + // Neither alternate was updated, which means the rest of the + // ancestor path already has sufficient priority. + break; + } + node = node.return; + } +} + +function propagateContextChange( + workInProgress, + context, changedBits, renderExpirationTime ) { @@ -6432,11 +6830,11 @@ function propagateContextChange( var nextFiber = void 0; // Visit this fiber. - var list = fiber.contextDependencies; + var list = fiber.dependencies; if (list !== null) { nextFiber = fiber.child; - var dependency = list.first; + var dependency = list.firstContext; while (dependency !== null) { // Check if the context matches. if ( @@ -6447,7 +6845,7 @@ function propagateContextChange( if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate(renderExpirationTime); + var update = createUpdate(renderExpirationTime, null); 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 @@ -6543,17 +6941,18 @@ function prepareToReadContext(workInProgress, renderExpirationTime) { lastContextDependency = null; lastContextWithAllBitsObserved = null; - var currentDependencies = workInProgress.contextDependencies; - if ( - currentDependencies !== null && - currentDependencies.expirationTime >= renderExpirationTime - ) { - // Context list has a pending update. Mark that this fiber performed work. - markWorkInProgressReceivedUpdate(); + var dependencies = workInProgress.dependencies; + if (dependencies !== null) { + var firstContext = dependencies.firstContext; + if (firstContext !== null) { + if (dependencies.expirationTime >= renderExpirationTime) { + // Context list has a pending update. Mark that this fiber performed work. + markWorkInProgressReceivedUpdate(); + } + // Reset the work-in-progress list + dependencies.firstContext = null; + } } - - // Reset the work-in-progress list - workInProgress.contextDependencies = null; } function readContext(context, observedBits) { @@ -6598,16 +6997,20 @@ function readContext(context, observedBits) { (function() { if (!(currentlyRenderingFiber !== null)) { throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); } })(); // This is the first dependency for this component. Create a new list. lastContextDependency = contextItem; - currentlyRenderingFiber.contextDependencies = { - first: contextItem, - expirationTime: NoWork + currentlyRenderingFiber.dependencies = { + expirationTime: NoWork, + firstContext: contextItem, + listeners: null, + responders: null }; } else { // Append a new context item. @@ -6747,9 +7150,10 @@ function cloneUpdateQueue(currentQueue) { return queue; } -function createUpdate(expirationTime) { - return { +function createUpdate(expirationTime, suspenseConfig) { + var update = { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: UpdateState, payload: null, @@ -6758,6 +7162,10 @@ function createUpdate(expirationTime) { next: null, nextEffect: null }; + { + update.priority = getCurrentPriorityLevel(); + } + return update; } function appendUpdateToQueue(queue, update) { @@ -7010,7 +7418,7 @@ function processUpdateQueue( // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTime(updateExpirationTime); + markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. resultState = getStateFromUpdate( @@ -7124,8 +7532,10 @@ function callCallback(callback, context) { (function() { if (!(typeof callback === "function")) { throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ) ); } })(); @@ -7179,6 +7589,12 @@ function commitUpdateEffects(effect, instance) { } } +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; + +function requestCurrentSuspenseConfig() { + return ReactCurrentBatchConfig.suspense; +} + var fakeInternalInstance = {}; var isArray$1 = Array.isArray; @@ -7252,7 +7668,9 @@ var didWarnAboutInvalidateContextType = void 0; (function() { { throw ReactError( - "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + Error( + "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + ) ); } })(); @@ -7305,9 +7723,14 @@ var classComponentUpdater = { enqueueSetState: function(inst, payload, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.payload = payload; if (callback !== undefined && callback !== null) { { @@ -7316,16 +7739,23 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.tag = ReplaceState; update.payload = payload; @@ -7336,16 +7766,23 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.tag = ForceUpdate; if (callback !== undefined && callback !== null) { @@ -7355,7 +7792,9 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); } @@ -7938,11 +8377,6 @@ function mountClassInstance( } if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( - workInProgress, - instance - ); - ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -7950,7 +8384,7 @@ function mountClassInstance( } if (warnAboutDeprecatedLifecycles) { - ReactStrictModeWarnings.recordDeprecationWarnings( + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance ); @@ -8358,7 +8792,9 @@ var warnForMissingKey = function(child) {}; (function() { if (!(typeof child._store === "object")) { throw ReactError( - "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." + Error( + "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8420,7 +8856,9 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!(ownerFiber.tag === ClassComponent)) { throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); } })(); @@ -8429,9 +8867,11 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!inst) { throw ReactError( - "Missing owner for string ref " + - mixedRef + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + mixedRef + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8463,16 +8903,20 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!(typeof mixedRef === "string")) { throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); } })(); (function() { if (!element._owner) { throw ReactError( - "Element ref was specified as a string (" + - mixedRef + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + mixedRef + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } })(); @@ -8493,12 +8937,14 @@ function throwOnInvalidObjectType(returnFiber, newChild) { (function() { { throw ReactError( - "Objects are not valid as a React child (found: " + - (Object.prototype.toString.call(newChild) === "[object Object]" - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + - addendum + Error( + "Objects are not valid as a React child (found: " + + (Object.prototype.toString.call(newChild) === "[object Object]" + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + + addendum + ) ); } })(); @@ -9168,7 +9614,9 @@ function ChildReconciler(shouldTrackSideEffects) { (function() { if (!(typeof iteratorFn === "function")) { throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -9223,7 +9671,7 @@ function ChildReconciler(shouldTrackSideEffects) { var newChildren = iteratorFn.call(newChildrenIterable); (function() { if (!(newChildren != null)) { - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); } })(); @@ -9601,8 +10049,10 @@ function ChildReconciler(shouldTrackSideEffects) { (function() { { throw ReactError( - (Component.displayName || Component.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (Component.displayName || Component.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) ); } })(); @@ -9623,7 +10073,7 @@ var mountChildFibers = ChildReconciler(false); function cloneChildFibers(current$$1, workInProgress) { (function() { if (!(current$$1 === null || workInProgress.child === current$$1.child)) { - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); } })(); @@ -9652,6 +10102,15 @@ function cloneChildFibers(current$$1, workInProgress) { newChild.sibling = null; } +// Reset a workInProgress child set to prepare it for a second pass. +function resetChildFibers(workInProgress, renderExpirationTime) { + var child = workInProgress.child; + while (child !== null) { + resetWorkInProgress(child, renderExpirationTime); + child = child.sibling; + } +} + var NO_CONTEXT = {}; var contextStackCursor$1 = createCursor(NO_CONTEXT); @@ -9662,7 +10121,9 @@ function requiredContext(c) { (function() { if (!(c !== NO_CONTEXT)) { throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -9721,46 +10182,188 @@ function pushHostContext(fiber) { push(contextStackCursor$1, nextContext, fiber); } -function pushHostContextForEventComponent(fiber) { - var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContextForEventComponent(context); - - // Don't push this Fiber's context unless it's unique. - if (context === nextContext) { +function popHostContext(fiber) { + // Do not pop unless this Fiber provided the current context. + // pushHostContext() only pushes Fibers that provide unique contexts. + if (contextFiberStackCursor.current !== fiber) { return; } - // Track the context and the Fiber that provided it. - // This enables us to pop only Fibers that provide unique contexts. - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, nextContext, fiber); + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); } -function pushHostContextForEventTarget(fiber) { - var context = requiredContext(contextStackCursor$1.current); - var eventTargetType = fiber.type.type; - var nextContext = getChildHostContextForEventTarget(context, eventTargetType); +var DefaultSuspenseContext = 0; - // Don't push this Fiber's context unless it's unique. - if (context === nextContext) { - return; +// The Suspense Context is split into two parts. The lower bits is +// inherited deeply down the subtree. The upper bits only affect +// this immediate suspense boundary and gets reset each new +// boundary or suspense list. +var SubtreeSuspenseContextMask = 1; + +// Subtree Flags: + +// InvisibleParentSuspenseContext indicates that one of our parent Suspense +// boundaries is not currently showing visible main content. +// Either because it is already showing a fallback or is not mounted at all. +// We can use this to determine if it is desirable to trigger a fallback at +// the parent. If not, then we might need to trigger undesirable boundaries +// and/or suspend the commit to avoid hiding the parent content. +var InvisibleParentSuspenseContext = 1; + +// Shallow Flags: + +// ForceSuspenseFallback can be used by SuspenseList to force newly added +// items into their fallback state during one of the render passes. +var ForceSuspenseFallback = 2; + +var suspenseStackCursor = createCursor(DefaultSuspenseContext); + +function hasSuspenseContext(parentContext, flag) { + return (parentContext & flag) !== 0; +} + +function setDefaultShallowSuspenseContext(parentContext) { + return parentContext & SubtreeSuspenseContextMask; +} + +function setShallowSuspenseContext(parentContext, shallowContext) { + return (parentContext & SubtreeSuspenseContextMask) | shallowContext; +} + +function addSubtreeSuspenseContext(parentContext, subtreeContext) { + return parentContext | subtreeContext; +} + +function pushSuspenseContext(fiber, newContext) { + push(suspenseStackCursor, newContext, fiber); +} + +function popSuspenseContext(fiber) { + pop(suspenseStackCursor, fiber); +} + +// TODO: This is now an empty object. Should we switch this to a boolean? +// Alternatively we can make this use an effect tag similar to SuspenseList. + +function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { + // If it was the primary children that just suspended, capture and render the + var nextState = workInProgress.memoizedState; + if (nextState !== null) { + return false; + } + var props = workInProgress.memoizedProps; + // In order to capture, the Suspense component must have a fallback prop. + if (props.fallback === undefined) { + return false; + } + // Regular boundaries always capture. + if (props.unstable_avoidThisFallback !== true) { + return true; + } + // If it's a boundary we should avoid, then we prefer to bubble up to the + // parent boundary if it is currently invisible. + if (hasInvisibleParent) { + return false; } + // If the parent is not able to handle it, we must handle it. + return true; +} - // Track the context and the Fiber that provided it. - // This enables us to pop only Fibers that provide unique contexts. - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, nextContext, fiber); +function findFirstSuspended(row) { + var node = row; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + return node; + } + } else if ( + node.tag === SuspenseListComponent && + // revealOrder undefined can't be trusted because it don't + // keep track of whether it suspended or not. + node.memoizedProps.revealOrder !== undefined + ) { + var didSuspend = (node.effectTag & DidCapture) !== NoEffect; + if (didSuspend) { + return node; + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) { + return null; + } + while (node.sibling === null) { + if (node.return === null || node.return === row) { + return null; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; } -function popHostContext(fiber) { - // Do not pop unless this Fiber provided the current context. - // pushHostContext() only pushes Fibers that provide unique contexts. - if (contextFiberStackCursor.current !== fiber) { - return; +var currentlyRenderingFiber$2 = null; +var currentListenerHookIndex = 0; + +function prepareToReadListenerHooks(workInProgress) { + currentlyRenderingFiber$2 = workInProgress; + currentListenerHookIndex = 0; +} + +function getListenerHooks() { + var listeners = void 0; + var dependencies = currentlyRenderingFiber$2.dependencies; + if (dependencies === null) { + dependencies = currentlyRenderingFiber$2.dependencies = { + expirationTime: NoWork, + firstContext: null, + listeners: [], + responders: null + }; + } + listeners = dependencies.listeners; + if (listeners === null) { + dependencies.listeners = listeners = []; } + return listeners; +} - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); +function updateListenerHook(responder, props) { + var listeners = getListenerHooks(); + if (listeners.length === currentListenerHookIndex) { + listeners.push({ + responder: responder, + props: props + }); + currentListenerHookIndex++; + } else { + var currentListenerHook = listeners[currentListenerHookIndex++]; + currentListenerHook.responder = responder; + currentListenerHook.props = props; + } +} + +function createResponderInstance( + responder, + responderProps, + responderState, + target, + fiber +) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState, + target: target + }; } var NoEffect$1 = /* */ 0; @@ -9920,7 +10523,9 @@ function throwInvalidHookError() { (function() { { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } })(); @@ -10101,7 +10706,9 @@ function renderWithHooks( (function() { if (!!didRenderTooFewHooks) { throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); } })(); @@ -10189,7 +10796,7 @@ function updateWorkInProgressHook() { (function() { if (!(nextCurrentHook !== null)) { throw ReactError( - "Rendered more hooks than during the previous render." + Error("Rendered more hooks than during the previous render.") ); } })(); @@ -10257,7 +10864,9 @@ function updateReducer(reducer, initialArg, init) { (function() { if (!(queue !== null)) { throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); } })(); @@ -10290,7 +10899,7 @@ function updateReducer(reducer, initialArg, init) { } hook.memoizedState = newState; - // Don't persist the state accumlated from the render phase updates to + // Don't persist the state accumulated from the render phase updates to // the base state unless the queue is empty. // TODO: Not sure if this is the desired semantics, but it's what we // do for gDSFP. I can't remember why. @@ -10356,7 +10965,10 @@ function updateReducer(reducer, initialArg, init) { // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTime(updateExpirationTime); + markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ); // Process this update. if (_update.eagerReducer === reducer) { @@ -10489,6 +11101,12 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { } function mountEffect(create, deps) { + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } return mountEffectImpl( Update | Passive, UnmountPassive | MountPassive, @@ -10498,6 +11116,12 @@ function mountEffect(create, deps) { } function updateEffect(create, deps) { + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } return updateEffectImpl( Update | Passive, UnmountPassive | MountPassive, @@ -10651,7 +11275,9 @@ function dispatchAction(fiber, queue, action) { (function() { if (!(numberOfReRenders < RE_RENDER_LIMIT)) { throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); } })(); @@ -10678,11 +11304,15 @@ function dispatchAction(fiber, queue, action) { didScheduleRenderPhaseUpdate = true; var update = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, next: null }; + { + update.priority = getCurrentPriorityLevel(); + } if (renderPhaseUpdates === null) { renderPhaseUpdates = new Map(); } @@ -10698,19 +11328,31 @@ function dispatchAction(fiber, queue, action) { lastRenderPhaseUpdate.next = update; } } else { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } var currentTime = requestCurrentTime(); - var _expirationTime = computeExpirationForFiber(currentTime, fiber); + var _suspenseConfig = requestCurrentSuspenseConfig(); + var _expirationTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); var _update2 = { expirationTime: _expirationTime, + suspenseConfig: _suspenseConfig, action: action, eagerReducer: null, eagerState: null, next: null }; + { + _update2.priority = getCurrentPriorityLevel(); + } + // Append the update to the end of the list. var _last = queue.last; if (_last === null) { @@ -10766,10 +11408,9 @@ function dispatchAction(fiber, queue, action) { } } { - // jest isn't a 'global', it's just exposed to tests via a wrapped function - // further, this isn't a test file, so flow doesn't recognize the symbol. So... - // $FlowExpectedError - because requirements don't give a damn about your type sigs. + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(fiber); warnIfNotCurrentlyActingUpdatesInDev(fiber); } } @@ -10789,7 +11430,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }; var HooksDispatcherOnMountInDEV = null; @@ -10895,6 +11537,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + mountHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10969,6 +11616,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + updateHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -11043,6 +11695,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); return updateDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + updateHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -11128,6 +11785,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); mountHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + warnInvalidHookAccess(); + mountHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -11213,6 +11876,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); updateHookTypesDev(); return updateDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + warnInvalidHookAccess(); + updateHookTypesDev(); + updateListenerHook(responder, props); } }; } @@ -11482,7 +12151,9 @@ function prepareToHydrateHostInstance( (function() { { throw ReactError( - "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11512,7 +12183,9 @@ function prepareToHydrateHostTextInstance(fiber) { (function() { { throw ReactError( - "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11562,7 +12235,9 @@ function skipPastDehydratedSuspenseInstance(fiber) { (function() { { throw ReactError( - "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11571,7 +12246,9 @@ function skipPastDehydratedSuspenseInstance(fiber) { (function() { if (!suspenseInstance) { throw ReactError( - "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11659,6 +12336,9 @@ var didWarnAboutGetDerivedStateOnFunctionComponent = void 0; var didWarnAboutFunctionRefs = void 0; var didWarnAboutReassigningProps = void 0; var didWarnAboutMaxDuration = void 0; +var didWarnAboutRevealOrder = void 0; +var didWarnAboutTailOptions = void 0; +var didWarnAboutDefaultPropsOnFunctionComponent = void 0; { didWarnAboutBadClass = {}; @@ -11668,6 +12348,9 @@ var didWarnAboutMaxDuration = void 0; didWarnAboutFunctionRefs = {}; didWarnAboutReassigningProps = false; didWarnAboutMaxDuration = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; } function reconcileChildren( @@ -11769,6 +12452,9 @@ function updateForwardRef( // The rest is a fork of updateFunctionComponent var nextChildren = void 0; prepareToReadContext(workInProgress, renderExpirationTime); + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } { ReactCurrentOwner$3.current = workInProgress; setCurrentPhase("render"); @@ -11787,6 +12473,9 @@ function updateForwardRef( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } nextChildren = renderWithHooks( current$$1, workInProgress, @@ -12071,6 +12760,9 @@ function updateFunctionComponent( var nextChildren = void 0; prepareToReadContext(workInProgress, renderExpirationTime); + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } { ReactCurrentOwner$3.current = workInProgress; setCurrentPhase("render"); @@ -12089,6 +12781,9 @@ function updateFunctionComponent( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } nextChildren = renderWithHooks( current$$1, workInProgress, @@ -12342,7 +13037,9 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { (function() { if (!(updateQueue !== null)) { throw ReactError( - "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." + 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." + ) ); } })(); @@ -12440,10 +13137,13 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { // Check the host config to see if the children are offscreen/hidden. if ( - renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps) ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. workInProgress.expirationTime = workInProgress.childExpirationTime = Never; return null; @@ -12585,10 +13285,12 @@ function mountLazyComponent( (function() { { throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ) ); } })(); @@ -12677,7 +13379,9 @@ function mountIndeterminateComponent( var context = getMaskedContext(workInProgress, unmaskedContext); prepareToReadContext(workInProgress, renderExpirationTime); - + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } var value = void 0; { @@ -12791,6 +13495,9 @@ function mountIndeterminateComponent( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } value = renderWithHooks( null, workInProgress, @@ -12844,16 +13551,33 @@ function validateFunctionComponentInDev(workInProgress, Component) { } } - if (typeof Component.getDerivedStateFromProps === "function") { + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { var componentName = getComponentName(Component) || "Unknown"; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) { + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { warningWithoutStack$1( false, - "%s: Function components do not support getDerivedStateFromProps.", + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", componentName ); - didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true; + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } + + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + warningWithoutStack$1( + false, + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; } } @@ -12861,19 +13585,31 @@ function validateFunctionComponentInDev(workInProgress, Component) { typeof Component.contextType === "object" && Component.contextType !== null ) { - var _componentName2 = getComponentName(Component) || "Unknown"; + var _componentName3 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName2]) { + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { warningWithoutStack$1( false, "%s: Function components do not support contextType.", - _componentName2 + _componentName3 ); - didWarnAboutContextTypeOnFunctionComponent[_componentName2] = true; + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; } } } +// TODO: This is now an empty object. Should we just make it a boolean? +var SUSPENDED_MARKER = {}; + +function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { + // If the context is telling us that we should show a fallback, and we're not + // already showing content, then we should show the fallback instead. + return ( + hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && + (current$$1 === null || current$$1.memoizedState !== null) + ); +} + function updateSuspenseComponent( current$$1, workInProgress, @@ -12882,32 +13618,51 @@ function updateSuspenseComponent( var mode = workInProgress.mode; var nextProps = workInProgress.pendingProps; + // This is used by DevTools to force a boundary to suspend. { if (shouldSuspend(workInProgress)) { workInProgress.effectTag |= DidCapture; } } - // We should attempt to render the primary children unless this boundary - // already suspended during this render (`alreadyCaptured` is true). - var nextState = workInProgress.memoizedState; + var suspenseContext = suspenseStackCursor.current; - var nextDidTimeout = void 0; - if ((workInProgress.effectTag & DidCapture) === NoEffect) { - // This is the first attempt. - nextState = null; - nextDidTimeout = false; - } else { + var nextState = null; + var nextDidTimeout = false; + + if ( + (workInProgress.effectTag & DidCapture) !== NoEffect || + shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) + ) { // Something in this boundary's subtree already suspended. Switch to // rendering the fallback children. - nextState = { - fallbackExpirationTime: - nextState !== null ? nextState.fallbackExpirationTime : NoWork - }; + nextState = SUSPENDED_MARKER; nextDidTimeout = true; workInProgress.effectTag &= ~DidCapture; + } else { + // Attempting the main content + if (current$$1 === null || current$$1.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); + { if ("maxDuration" in nextProps) { if (!didWarnAboutMaxDuration) { @@ -12960,6 +13715,7 @@ function updateSuspenseComponent( tryToClaimNextHydratableInstance(workInProgress); // This could've changed the tag if this was a dehydrated suspense component. if (workInProgress.tag === DehydratedSuspenseComponent) { + popSuspenseContext(workInProgress); return updateDehydratedSuspenseComponent( null, workInProgress, @@ -12980,15 +13736,21 @@ function updateSuspenseComponent( NoWork, null ); + primaryChildFragment.return = workInProgress; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var progressedState = workInProgress.memoizedState; var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child; primaryChildFragment.child = progressedPrimaryChild; + var progressedChild = progressedPrimaryChild; + while (progressedChild !== null) { + progressedChild.return = primaryChildFragment; + progressedChild = progressedChild.sibling; + } } var fallbackChildFragment = createFiberFromFragment( @@ -12997,12 +13759,12 @@ function updateSuspenseComponent( renderExpirationTime, null ); + fallbackChildFragment.return = workInProgress; primaryChildFragment.sibling = fallbackChildFragment; child = primaryChildFragment; // Skip the primary children, and continue working on the // fallback children. next = fallbackChildFragment; - child.return = next.return = workInProgress; } else { // Mount the primary children without an intermediate fragment fiber. var nextPrimaryChildren = nextProps.children; @@ -13031,9 +13793,10 @@ function updateSuspenseComponent( currentPrimaryChildFragment.pendingProps, NoWork ); + _primaryChildFragment.return = workInProgress; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var _progressedState = workInProgress.memoizedState; var _progressedPrimaryChild = _progressedState !== null @@ -13041,6 +13804,11 @@ function updateSuspenseComponent( : workInProgress.child; if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { _primaryChildFragment.child = _progressedPrimaryChild; + var _progressedChild = _progressedPrimaryChild; + while (_progressedChild !== null) { + _progressedChild.return = _primaryChildFragment; + _progressedChild = _progressedChild.sibling; + } } } @@ -13059,17 +13827,18 @@ function updateSuspenseComponent( // Clone the fallback child fragment, too. These we'll continue // working on. - var _fallbackChildFragment = (_primaryChildFragment.sibling = createWorkInProgress( + var _fallbackChildFragment = createWorkInProgress( currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime - )); + ); + _fallbackChildFragment.return = workInProgress; + _primaryChildFragment.sibling = _fallbackChildFragment; child = _primaryChildFragment; _primaryChildFragment.childExpirationTime = NoWork; // Skip the primary children, and continue working on the // fallback children. next = _fallbackChildFragment; - child.return = next.return = workInProgress; } else { // No longer suspended. Switch back to showing the primary children, // and remove the intermediate fragment fiber. @@ -13107,21 +13876,30 @@ function updateSuspenseComponent( NoWork, null ); + _primaryChildFragment2.return = workInProgress; _primaryChildFragment2.child = _currentPrimaryChild; + if (_currentPrimaryChild !== null) { + _currentPrimaryChild.return = _primaryChildFragment2; + } // Even though we're creating a new fiber, there are no new children, // because we're reusing an already mounted tree. So we don't need to // schedule a placement. // primaryChildFragment.effectTag |= Placement; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var _progressedState2 = workInProgress.memoizedState; var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child; _primaryChildFragment2.child = _progressedPrimaryChild2; + var _progressedChild2 = _progressedPrimaryChild2; + while (_progressedChild2 !== null) { + _progressedChild2.return = _primaryChildFragment2; + _progressedChild2 = _progressedChild2.sibling; + } } // Because primaryChildFragment is a new fiber that we're inserting as the @@ -13138,19 +13916,20 @@ function updateSuspenseComponent( } // Create a fragment from the fallback children, too. - var _fallbackChildFragment2 = (_primaryChildFragment2.sibling = createFiberFromFragment( + var _fallbackChildFragment2 = createFiberFromFragment( _nextFallbackChildren2, mode, renderExpirationTime, null - )); + ); + _fallbackChildFragment2.return = workInProgress; + _primaryChildFragment2.sibling = _fallbackChildFragment2; _fallbackChildFragment2.effectTag |= Placement; child = _primaryChildFragment2; _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the // fallback children. next = _fallbackChildFragment2; - child.return = next.return = workInProgress; } else { // Still haven't timed out. Continue rendering the children, like we // normally do. @@ -13185,7 +13964,9 @@ function retrySuspenseComponentWithoutHydrating( (function() { if (!(returnFiber !== null)) { throw ReactError( - "Suspense boundaries are never on the root. This is probably a bug in React." + Error( + "Suspense boundaries are never on the root. This is probably a bug in React." + ) ); } })(); @@ -13199,6 +13980,8 @@ function retrySuspenseComponentWithoutHydrating( current$$1.nextEffect = null; current$$1.effectTag = Deletion; + popSuspenseContext(workInProgress); + // Upgrade this work in progress to a real Suspense component. workInProgress.tag = SuspenseComponent; workInProgress.stateNode = null; @@ -13214,6 +13997,10 @@ function updateDehydratedSuspenseComponent( workInProgress, renderExpirationTime ) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); var suspenseInstance = workInProgress.stateNode; if (current$$1 === null) { // During the first pass, we'll bail out and not drill into the children. @@ -13306,6 +14093,382 @@ function updateDehydratedSuspenseComponent( } } +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderExpirationTime +) { + // 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; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + if (node.expirationTime < renderExpirationTime) { + node.expirationTime = renderExpirationTime; + } + var alternate = node.alternate; + if ( + alternate !== null && + alternate.expirationTime < renderExpirationTime + ) { + alternate.expirationTime = renderExpirationTime; + } + scheduleWorkOnParentPath(node.return, renderExpirationTime); + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) { + return; + } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} + +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; + } + row = row.sibling; + } + return lastContentRow; +} + +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + case "forward": + case "backward": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + default: + warning$1( + false, + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { + warning$1( + false, + "%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; + warning$1( + false, + '"%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; + warning$1( + false, + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); + } + } + } +} + +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + warning$1( + false, + "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; + } + } + 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 { + var iteratorFn = getIteratorFn(children); + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + _i++; + } + } + } else { + warning$1( + false, + '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 +) { + var renderState = workInProgress.memoizedState; + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailExpiration = 0; + 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. +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + 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$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + + var suspenseContext = suspenseStackCursor.current; + + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.effectTag |= DidCapture; + } else { + var didSuspendBefore = + current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; + 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, + renderExpirationTime + ); + } + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } + pushSuspenseContext(workInProgress, suspenseContext); + + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched 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 = void 0; + 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; + } + case "together": { + initSuspenseListRenderState( + workInProgress, + 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 workInProgress.child; +} + function updatePortalComponent( current$$1, workInProgress, @@ -13469,11 +14632,15 @@ function updateContextConsumer( return workInProgress.child; } -function updateEventComponent$1( +function updateFundamentalComponent$1( current$$1, workInProgress, renderExpirationTime ) { + var fundamentalImpl = workInProgress.type.impl; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; @@ -13483,38 +14650,6 @@ function updateEventComponent$1( nextChildren, renderExpirationTime ); - pushHostContextForEventComponent(workInProgress); - return workInProgress.child; -} - -function updateEventTarget(current$$1, workInProgress, renderExpirationTime) { - var type = workInProgress.type.type; - var nextProps = workInProgress.pendingProps; - var eventTargetChild = getEventTargetChildElement(type, nextProps); - - { - !(nextProps.children == null) - ? warning$1(false, "Event targets should not have children.") - : void 0; - } - if (eventTargetChild !== null) { - var child = (workInProgress.child = createFiberFromTypeAndProps( - eventTargetChild.type, - null, - eventTargetChild.props, - null, - workInProgress.mode, - renderExpirationTime - )); - child.return = workInProgress; - - if (current$$1 === null || current$$1.child === null) { - child.effectTag = Placement; - } - } else { - reconcileChildren(current$$1, workInProgress, null, renderExpirationTime); - } - pushHostContextForEventTarget(workInProgress); return workInProgress.child; } @@ -13530,8 +14665,8 @@ function bailoutOnAlreadyFinishedWork( cancelWorkTimer(workInProgress); if (current$$1 !== null) { - // Reuse previous context list - workInProgress.contextDependencies = current$$1.contextDependencies; + // Reuse previous dependencies + workInProgress.dependencies = current$$1.dependencies; } if (enableProfilerTimer) { @@ -13654,6 +14789,18 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { break; case HostComponent: pushHostContext(workInProgress); + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(workInProgress.type, newProps) + ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + // Schedule this fiber to re-render at offscreen priority. Then bailout. + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } break; case ClassComponent: { var Component = workInProgress.type; @@ -13700,6 +14847,10 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ); } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient // priority. Bailout. var child = bailoutOnAlreadyFinishedWork( @@ -13715,11 +14866,20 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { return null; } } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } break; } case DehydratedSuspenseComponent: { if (enableSuspenseServerRenderer) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has // been unsuspended it has committed as a regular Suspense component. // If it needs to be retried, it should have work scheduled on it. @@ -13727,15 +14887,46 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } break; } - case EventComponent: - if (enableEventAPI) { - pushHostContextForEventComponent(workInProgress); + case SuspenseListComponent: { + var didSuspendBefore = + (current$$1.effectTag & DidCapture) !== NoEffect; + + var childExpirationTime = workInProgress.childExpirationTime; + if (childExpirationTime < renderExpirationTime) { + // 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. + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (didSuspendBefore) { + workInProgress.effectTag |= DidCapture; + } + return null; } - break; - case EventTarget: { - if (enableEventAPI) { - pushHostContextForEventTarget(workInProgress); + + if (didSuspendBefore) { + // 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$$1, + workInProgress, + renderExpirationTime + ); + } + + // 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; } + pushSuspenseContext(workInProgress, suspenseStackCursor.current); break; } } @@ -13920,19 +15111,16 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } break; } - case EventComponent: { - if (enableEventAPI) { - return updateEventComponent$1( - current$$1, - workInProgress, - renderExpirationTime - ); - } - break; + case SuspenseListComponent: { + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } - case EventTarget: { - if (enableEventAPI) { - return updateEventTarget( + case FundamentalComponent: { + if (enableFundamentalAPI) { + return updateFundamentalComponent$1( current$$1, workInProgress, renderExpirationTime @@ -13944,12 +15132,28 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { (function() { { throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); } +function createFundamentalStateInstance(currentFiber, props, impl, state) { + return { + currentFiber: currentFiber, + impl: impl, + instance: null, + prevProps: null, + props: props, + state: state + }; +} + +var emptyObject$1 = {}; +var isArray$2 = Array.isArray; + function markUpdate(workInProgress) { // Tag the fiber with an update effect. This turns a Placement into // a PlacementAndUpdate. @@ -13979,6 +15183,8 @@ if (supportsMutation) { while (node !== null) { if (node.tag === HostComponent || node.tag === HostText) { appendInitialChild(parent, node.stateNode); + } else if (node.tag === FundamentalComponent) { + appendInitialChild(parent, node.stateNode.instance); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -14083,6 +15289,15 @@ if (supportsMutation) { _instance = cloneHiddenTextInstance(_instance, text, node); } appendInitialChild(parent, _instance); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance2 = node.stateNode.instance; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props = node.memoizedProps; + var _type = node.type; + _instance2 = cloneHiddenInstance(_instance2, _type, _props, node); + } + appendInitialChild(parent, _instance2); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -14161,13 +15376,22 @@ if (supportsMutation) { } appendChildToContainerChildSet(containerChildSet, instance); } else if (node.tag === HostText) { - var _instance2 = node.stateNode; + var _instance3 = node.stateNode; if (needsVisibilityToggle && isHidden) { // This child is inside a timed out tree. Hide it. var text = node.memoizedProps; - _instance2 = cloneHiddenTextInstance(_instance2, text, node); + _instance3 = cloneHiddenTextInstance(_instance3, text, node); } - appendChildToContainerChildSet(containerChildSet, _instance2); + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance4 = node.stateNode.instance; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props2 = node.memoizedProps; + var _type2 = node.type; + _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node); + } + appendChildToContainerChildSet(containerChildSet, _instance4); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -14343,6 +15567,69 @@ if (supportsMutation) { }; } +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + tailNode = tailNode.sibling; + } + // Next we're simply going to delete all insertions after the + // last rendered item. + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } + break; + } + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } + _tailNode = _tailNode.sibling; + } + // Next we're simply going to delete all insertions after the + // last rendered item. + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + break; + } + } +} + function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; @@ -14393,6 +15680,20 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); + if (enableFlareAPI) { + var prevResponders = current.memoizedProps.responders; + var nextResponders = newProps.responders; + var instance = workInProgress.stateNode; + if (prevResponders !== nextResponders) { + updateEventResponders( + nextResponders, + instance, + rootContainerInstance, + workInProgress + ); + } + } + if (current.ref !== workInProgress.ref) { markRef$1(workInProgress); } @@ -14401,7 +15702,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { if (!(workInProgress.stateNode !== null)) { throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14430,7 +15733,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } else { - var instance = createInstance( + var _instance5 = createInstance( type, newProps, rootContainerInstance, @@ -14438,14 +15741,26 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress ); - appendAllChildren(instance, workInProgress, false, false); + appendAllChildren(_instance5, workInProgress, false, false); + + if (enableFlareAPI) { + var responders = newProps.responders; + if (responders != null) { + updateEventResponders( + responders, + _instance5, + rootContainerInstance, + workInProgress + ); + } + } // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. if ( finalizeInitialChildren( - instance, + _instance5, type, newProps, rootContainerInstance, @@ -14454,7 +15769,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { ) { markUpdate(workInProgress); } - workInProgress.stateNode = instance; + workInProgress.stateNode = _instance5; } if (workInProgress.ref !== null) { @@ -14476,7 +15791,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { if (!(workInProgress.stateNode !== null)) { throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14503,6 +15820,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { case ForwardRef: break; case SuspenseComponent: { + popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; if ((workInProgress.effectTag & DidCapture) !== NoEffect) { // Something suspended. Re-render with the fallback children. @@ -14523,15 +15841,8 @@ function completeWork(current, workInProgress, renderExpirationTime) { prevDidTimeout = prevState !== null; if (!nextDidTimeout && prevState !== null) { // We just switched from the fallback to the normal children. - - // Mark the event time of the switching from fallback to normal children, - // based on the start of when we first showed the fallback. This time - var fallbackExpirationTime = prevState.fallbackExpirationTime; - markRenderEventTime(fallbackExpirationTime); - // Delete the fallback. // TODO: Would it be better to store the fallback fragment on - // the stateNode during the begin phase? var currentFallbackChild = current.child.sibling; if (currentFallbackChild !== null) { // Deletions go at the beginning of the return fiber's effect list @@ -14549,13 +15860,37 @@ function completeWork(current, workInProgress, renderExpirationTime) { } if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in concurrent mode we can suspend, + // If this subtreee is running in batched 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 & ConcurrentMode) !== NoContext) { - renderDidSuspend(); + if ((workInProgress.mode & BatchedMode) !== 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(); + } } } @@ -14579,6 +15914,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.effectTag |= Update; } } + if ( + enableSuspenseCallback && + workInProgress.updateQueue !== null && + workInProgress.memoizedProps.suspenseCallback != null + ) { + // Always notify the callback + workInProgress.effectTag |= Update; + } break; } case Fragment: @@ -14610,15 +15953,21 @@ function completeWork(current, workInProgress, renderExpirationTime) { } case DehydratedSuspenseComponent: { if (enableSuspenseServerRenderer) { + popSuspenseContext(workInProgress); if (current === null) { var _wasHydrated2 = popHydrationState(workInProgress); (function() { if (!_wasHydrated2) { throw ReactError( - "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ) ); } })(); + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } skipPastDehydratedSuspenseInstance(workInProgress); } else if ((workInProgress.effectTag & DidCapture) === NoEffect) { // This boundary did not suspend so it's now hydrated. @@ -14633,55 +15982,239 @@ function completeWork(current, workInProgress, renderExpirationTime) { } break; } - case EventComponent: { - if (enableEventAPI) { - popHostContext(workInProgress); - var _rootContainerInstance2 = getRootHostContainer(); - var responder = workInProgress.type.responder; - var eventComponentInstance = workInProgress.stateNode; - - if (eventComponentInstance === null) { - var responderState = null; - if (responder.createInitialState !== undefined) { - responderState = responder.createInitialState(newProps); + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. We don't do anything + // in this mode. + break; + } + + var didSuspendAlready = + (workInProgress.effectTag & DidCapture) !== NoEffect; + + var renderedTail = renderState.rendering; + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.effectTag & DidCapture) === NoEffect); + if (!cannotBeSuspended) { + var row = workInProgress.child; + while (row !== null) { + var suspended = findFirstSuspended(row); + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.effectTag |= 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. + var newThennables = suspended.updateQueue; + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.effectTag |= 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. + workInProgress.firstEffect = workInProgress.lastEffect = null; + // Reset the child fibers to their original state. + resetChildFibers(workInProgress, renderExpirationTime); + + // Set up the Suspense Context to force suspense and immediately + // rerender the children. + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } + row = row.sibling; + } } - eventComponentInstance = workInProgress.stateNode = { - currentFiber: workInProgress, - props: newProps, - responder: responder, - rootEventTypes: null, - rootInstance: _rootContainerInstance2, - state: responderState - }; - markUpdate(workInProgress); } else { - // Update the props on the event component state node - eventComponentInstance.props = newProps; - // Update the root container, so we can properly unmount events at some point - eventComponentInstance.rootInstance = _rootContainerInstance2; - // Update the current fiber - eventComponentInstance.currentFiber = workInProgress; - updateEventComponent(eventComponentInstance); + cutOffTailIfNeeded(renderState, false); + } + // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + if (_suspended !== null) { + workInProgress.effectTag |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, true); + // This might have been modified. + if ( + renderState.tail === null && + renderState.tailMode === "hidden" + ) { + // We need to delete the row we just rendered. + // Ensure we transfer the update queue to the parent. + var _newThennables = _suspended.updateQueue; + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.effectTag |= Update; + } + // Reset the effect list to what it w as 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. + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } + // We're done. + return null; + } + } else if ( + now() > renderState.tailExpiration && + renderExpirationTime > Never + ) { + // 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.effectTag |= 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. If we can show + // them, then they really have the same priority as this render. + // So we'll pick it back up the very next render pass once we've had + // an opportunity to yield for paint. + + var nextPriority = renderExpirationTime - 1; + workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; + if (enableSchedulerTracing) { + markSpawnedWork(nextPriority); + } + } + } + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } + renderState.last = renderedTail; + } + } + + if (renderState.tail !== null) { + // We still have tail rows to render. + if (renderState.tailExpiration === 0) { + // Heuristic for how long we're willing to spend rendering rows + // until we just give up and show what we have so far. + var TAIL_EXPIRATION_TIMEOUT_MS = 500; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + } + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.lastEffect = workInProgress.lastEffect; + next.sibling = null; + + // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + var suspenseContext = suspenseStackCursor.current; + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } + pushSuspenseContext(workInProgress, suspenseContext); + // Do a pass over the next row. + return next; } break; } - case EventTarget: { - if (enableEventAPI) { - popHostContext(workInProgress); - var _type = workInProgress.type.type; - var _rootContainerInstance3 = getRootHostContainer(); - var shouldUpdate = handleEventTarget( - _type, - newProps, - _rootContainerInstance3, - workInProgress - ); - // Update the latest props on the stateNode. This is used - // during the event phase to find the most current props. - workInProgress.stateNode.props = newProps; - if (shouldUpdate) { - markUpdate(workInProgress); + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalImpl = workInProgress.type.impl; + var fundamentalInstance = workInProgress.stateNode; + + if (fundamentalInstance === null) { + var getInitialState = fundamentalImpl.getInitialState; + var fundamentalState = void 0; + if (getInitialState !== undefined) { + fundamentalState = getInitialState(newProps); + } + fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance( + workInProgress, + newProps, + fundamentalImpl, + fundamentalState || {} + ); + var _instance6 = getFundamentalComponentInstance(fundamentalInstance); + fundamentalInstance.instance = _instance6; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } + appendAllChildren(_instance6, workInProgress, false, false); + mountFundamentalComponent(fundamentalInstance); + } else { + // We fire update in commit phase + var prevProps = fundamentalInstance.props; + fundamentalInstance.prevProps = prevProps; + fundamentalInstance.props = newProps; + fundamentalInstance.currentFiber = workInProgress; + if (supportsPersistence) { + var _instance7 = cloneFundamentalInstance(fundamentalInstance); + fundamentalInstance.instance = _instance7; + appendAllChildren(_instance7, workInProgress, false, false); + } + var shouldUpdate = shouldUpdateFundamentalComponent( + fundamentalInstance + ); + if (shouldUpdate) { + markUpdate(workInProgress); + } } } break; @@ -14690,7 +16223,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { { throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14699,15 +16234,263 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } -function shouldCaptureSuspense(workInProgress) { - // In order to capture, the Suspense component must have a fallback prop. - if (workInProgress.memoizedProps.fallback === undefined) { - return false; +function mountEventResponder( + responder, + responderProps, + instance, + rootContainerInstance, + fiber, + respondersMap +) { + var responderState = emptyObject$1; + var getInitialState = responder.getInitialState; + if (getInitialState !== null) { + responderState = getInitialState(responderProps); + } + var responderInstance = createResponderInstance( + responder, + responderProps, + responderState, + instance, + fiber + ); + mountResponderInstance( + responder, + responderInstance, + responderProps, + responderState, + instance, + rootContainerInstance + ); + respondersMap.set(responder, responderInstance); +} + +function updateEventResponder( + responder, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance +) { + (function() { + if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) { + throw ReactError( + Error( + "An invalid value was used as an event responder. Expect one or many event responders created via React.unstable_createResponer()." + ) + ); + } + })(); + if (visistedResponders.has(responder)) { + // show warning + return; + } + visistedResponders.add(responder); + var responderInstance = respondersMap.get(responder); + + if (responderInstance === undefined) { + // Mount + mountEventResponder( + responder, + props, + instance, + rootContainerInstance, + fiber, + respondersMap + ); + } else { + // Update + responderInstance.props = props; + responderInstance.fiber = fiber; + } +} + +function updateEventResponders( + responders, + instance, + rootContainerInstance, + fiber +) { + var visistedResponders = new Set(); + var dependencies = fiber.dependencies; + if (responders != null) { + if (dependencies === null) { + dependencies = fiber.dependencies = { + expirationTime: NoWork, + firstContext: null, + listeners: null, + responders: new Map() + }; + } + var respondersMap = dependencies.responders; + if (respondersMap === null) { + respondersMap = new Map(); + } + if (isArray$2(responders)) { + for (var i = 0, length = responders.length; i < length; i++) { + var _responders$i = responders[i], + type = _responders$i.type, + props = _responders$i.props; + + updateEventResponder( + type, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance + ); + } + } else { + var type = responders.type, + props = responders.props; + + updateEventResponder( + type, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance + ); + } + } + if (dependencies !== null) { + var _respondersMap = dependencies.responders; + if (_respondersMap !== null) { + // Unmount + var mountedResponders = Array.from(_respondersMap.keys()); + for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { + var mountedResponder = mountedResponders[_i]; + if (!visistedResponders.has(mountedResponder)) { + var responderInstance = _respondersMap.get(mountedResponder); + unmountResponderInstance(responderInstance); + _respondersMap.delete(mountedResponder); + } + } + } + } +} + +function unwindWork(workInProgress, renderExpirationTime) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; + if (isContextProvider(Component)) { + popContext(workInProgress); + } + var effectTag = workInProgress.effectTag; + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + return null; + } + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; + (function() { + if (!((_effectTag & DidCapture) === NoEffect)) { + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + } + })(); + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var _effectTag2 = workInProgress.effectTag; + if (_effectTag2 & ShouldCapture) { + workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; + // Captured a suspense effect. Re-render the boundary. + return workInProgress; + } + return null; + } + case DehydratedSuspenseComponent: { + if (enableSuspenseServerRenderer) { + // TODO: popHydrationState + popSuspenseContext(workInProgress); + var _effectTag3 = workInProgress.effectTag; + if (_effectTag3 & ShouldCapture) { + workInProgress.effectTag = + (_effectTag3 & ~ShouldCapture) | DidCapture; + // Captured a suspense effect. Re-render the boundary. + return workInProgress; + } + } + 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. + return null; + } + case HostPortal: + popHostContainer(workInProgress); + return null; + case ContextProvider: + popProvider(workInProgress); + return null; + default: + return null; + } +} + +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } + break; + } + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + break; + } + case HostComponent: { + popHostContext(interruptedWork); + break; + } + case HostPortal: + popHostContainer(interruptedWork); + break; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; + case DehydratedSuspenseComponent: + if (enableSuspenseServerRenderer) { + // TODO: popHydrationState + popSuspenseContext(interruptedWork); + } + break; + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; + case ContextProvider: + popProvider(interruptedWork); + break; + default: + break; } - // If it was the primary children that just suspended, capture and render the - // fallback. Otherwise, don't capture and bubble to the next boundary. - var nextState = workInProgress.memoizedState; - return nextState === null; } function createCapturedValue(value, source) { @@ -14721,47 +16504,23 @@ function createCapturedValue(value, source) { } // Module provided by RN: -/** - * Intercept lifecycle errors and ensure they are shown with the correct stack - * trace within the native redbox component. - */ -function showErrorDialog(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - - var errorToHandle = void 0; - - // Typically Errors are thrown but eg strings or null can be thrown as well. - if (error instanceof Error) { - var message = error.message, - name = error.name; - - var summary = message ? name + ": " + message : name; - - errorToHandle = error; - - try { - errorToHandle.message = - summary + "\n\nThis error is located at:" + componentStack; - } catch (e) {} - } else if (typeof error === "string") { - errorToHandle = new Error( - error + "\n\nThis error is located at:" + componentStack +(function() { + if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog + .showErrorDialog === "function" + ) + ) { + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") ); - } else { - errorToHandle = new Error("Unspecified error at:" + componentStack); } +})(); - ReactNativePrivateInterface.ExceptionsManager.handleException( - errorToHandle, - false +function showErrorDialog(capturedError) { + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError ); - - // Return false here to prevent ReactFiberErrorLogger default behavior of - // logging error details to console.error. Calls to console.error are - // automatically routed to the native redbox controller, which we've already - // done above by calling ExceptionsManager. - return false; } function logCapturedError(capturedError) { @@ -15011,14 +16770,15 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case HostText: case HostPortal: case IncompleteClassComponent: - case EventTarget: // Nothing to do for these component types return; default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15087,8 +16847,19 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } function commitPassiveHookEffects(finishedWork) { - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if ((finishedWork.effectTag & Passive) !== NoEffect) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + break; + } + default: + break; + } + } } function commitLifeCycles( @@ -15285,73 +17056,43 @@ function commitLifeCycles( if (enableProfilerTimer) { var onRender = finishedWork.memoizedProps.onRender; - if (enableSchedulerTracing) { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime(), - finishedRoot.memoizedInteractions - ); - } else { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime() - ); + if (typeof onRender === "function") { + if (enableSchedulerTracing) { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime(), + finishedRoot.memoizedInteractions + ); + } else { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime() + ); + } } } return; } case SuspenseComponent: + case SuspenseListComponent: case IncompleteClassComponent: + case FundamentalComponent: return; - case EventTarget: { - if (enableEventAPI) { - var _type = finishedWork.type.type; - var _props = finishedWork.memoizedProps; - var _instance3 = finishedWork.stateNode; - var parentInstance = null; - - var node = finishedWork.return; - // Traverse up the fiber tree until we find the parent host node. - while (node !== null) { - if (node.tag === HostComponent) { - parentInstance = node.stateNode; - break; - } else if (node.tag === HostRoot) { - parentInstance = node.stateNode.containerInfo; - break; - } - node = node.return; - } - (function() { - if (!(parentInstance !== null)) { - throw ReactError( - "This should have a parent host component initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); - commitEventTarget(_type, _props, _instance3, parentInstance); - } - return; - } - case EventComponent: { - if (enableEventAPI) { - mountEventComponent(finishedWork.stateNode); - } - return; - } default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15372,11 +17113,11 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { unhideInstance(node.stateNode, node.memoizedProps); } } else if (node.tag === HostText) { - var _instance4 = node.stateNode; + var _instance3 = node.stateNode; if (isHidden) { - hideTextInstance(_instance4); + hideTextInstance(_instance3); } else { - unhideTextInstance(_instance4, node.memoizedProps); + unhideTextInstance(_instance3, node.memoizedProps); } } else if ( node.tag === SuspenseComponent && @@ -15487,6 +17228,25 @@ function commitUnmount(current$$1) { return; } case HostComponent: { + if (enableFlareAPI) { + var dependencies = current$$1.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + for ( + var i = 0, length = responderInstances.length; + i < length; + i++ + ) { + var responderInstance = responderInstances[i]; + unmountResponderInstance(responderInstance); + } + dependencies.responders = null; + } + } + } safelyDetachRef(current$$1); return; } @@ -15501,11 +17261,13 @@ function commitUnmount(current$$1) { } return; } - case EventComponent: { - if (enableEventAPI) { - var eventComponentInstance = current$$1.stateNode; - unmountEventComponent(eventComponentInstance); - current$$1.stateNode = null; + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = current$$1.stateNode; + if (fundamentalInstance !== null) { + unmountFundamentalComponent(fundamentalInstance); + current$$1.stateNode = null; + } } } } @@ -15555,12 +17317,14 @@ function detachFiber(current$$1) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; if (alternate !== null) { alternate.return = null; alternate.child = null; alternate.memoizedState = null; alternate.updateQueue = null; + alternate.dependencies = null; } } @@ -15585,8 +17349,7 @@ function commitContainer(finishedWork) { case ClassComponent: case HostComponent: case HostText: - case EventTarget: - case EventComponent: { + case FundamentalComponent: { return; } case HostRoot: @@ -15602,7 +17365,9 @@ function commitContainer(finishedWork) { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15621,7 +17386,9 @@ function getHostParentFiber(fiber) { (function() { { throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15691,25 +17458,33 @@ function commitPlacement(finishedWork) { // Note: these two variables *must* always be updated together. var parent = void 0; var isContainer = void 0; - + var parentStateNode = parentFiber.stateNode; switch (parentFiber.tag) { case HostComponent: - parent = parentFiber.stateNode; + parent = parentStateNode; isContainer = false; break; case HostRoot: - parent = parentFiber.stateNode.containerInfo; + parent = parentStateNode.containerInfo; isContainer = true; break; case HostPortal: - parent = parentFiber.stateNode.containerInfo; + parent = parentStateNode.containerInfo; isContainer = true; break; + case FundamentalComponent: + if (enableFundamentalAPI) { + parent = parentStateNode.instance; + isContainer = false; + } + // eslint-disable-next-line-no-fallthrough default: (function() { { throw ReactError( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15724,8 +17499,9 @@ function commitPlacement(finishedWork) { // children to find all the terminal nodes. var node = finishedWork; while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - var stateNode = node.stateNode; + var isHost = node.tag === HostComponent || node.tag === HostText; + if (isHost || node.tag === FundamentalComponent) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; if (before) { if (isContainer) { insertInContainerBefore(parent, stateNode, before); @@ -15781,23 +17557,31 @@ function unmountHostComponents(current$$1) { (function() { if (!(parent !== null)) { throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); + var parentStateNode = parent.stateNode; switch (parent.tag) { case HostComponent: - currentParent = parent.stateNode; + currentParent = parentStateNode; currentParentIsContainer = false; break findParent; case HostRoot: - currentParent = parent.stateNode.containerInfo; + currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; case HostPortal: - currentParent = parent.stateNode.containerInfo; + currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; + case FundamentalComponent: + if (enableFundamentalAPI) { + currentParent = parentStateNode.instance; + currentParentIsContainer = false; + } } parent = parent.return; } @@ -15814,6 +17598,16 @@ function unmountHostComponents(current$$1) { removeChild(currentParent, node.stateNode); } // Don't visit children because we already visited them. + } else if (node.tag === FundamentalComponent) { + var fundamentalNode = node.stateNode.instance; + commitNestedUnmounts(node); + // After all the children have unmounted, it is now safe to remove the + // node from the tree. + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, fundamentalNode); + } else { + removeChild(currentParent, fundamentalNode); + } } else if ( enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent @@ -15892,6 +17686,11 @@ function commitWork(current$$1, finishedWork) { } case SuspenseComponent: { commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } } @@ -15944,7 +17743,9 @@ function commitWork(current$$1, finishedWork) { (function() { if (!(finishedWork.stateNode !== null)) { throw ReactError( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15957,9 +17758,6 @@ function commitWork(current$$1, finishedWork) { commitTextUpdate(textInstance, oldText, newText); return; } - case EventTarget: { - return; - } case HostRoot: { return; } @@ -15968,19 +17766,30 @@ function commitWork(current$$1, finishedWork) { } case SuspenseComponent: { commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } case IncompleteClassComponent: { return; } - case EventComponent: { + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = finishedWork.stateNode; + updateFundamentalComponent(fundamentalInstance); + } return; } default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15998,25 +17807,31 @@ function commitSuspenseComponent(finishedWork) { } else { newDidTimeout = true; primaryChildParent = finishedWork.child; - if (newState.fallbackExpirationTime === NoWork) { - // If the children had not already timed out, record the time. - // This is used to compute the elapsed time during subsequent - // attempts to render the children. - // We model this as a normal pri expiration time since that's - // how we infer start time for updates. - newState.fallbackExpirationTime = computeAsyncExpirationNoBucket( - requestCurrentTime() - ); - } + markCommitTimeOfFallback(); } if (supportsMutation && primaryChildParent !== null) { hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); } + if (enableSuspenseCallback && newState !== null) { + var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; + if (typeof suspenseCallback === "function") { + var thenables = finishedWork.updateQueue; + if (thenables !== null) { + suspenseCallback(new Set(thenables)); + } + } else { + if (suspenseCallback !== undefined) { + warning$1(false, "Unexpected type for suspenseCallback."); + } + } + } +} + +function attachSuspenseRetryListeners(finishedWork) { // If this boundary just timed out, then it will have a set of thenables. // For each thenable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. var thenables = finishedWork.updateQueue; if (thenables !== null) { finishedWork.updateQueue = null; @@ -16049,7 +17864,7 @@ var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, null); // Unmount the root by rendering null. update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property @@ -16064,7 +17879,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, null); update.tag = CaptureUpdate; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { @@ -16088,6 +17903,8 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // TODO: Warn in strict mode if getDerivedStateFromError is // not defined. markLegacyErrorBoundaryAsFailed(this); + + // Only log here if componentDidCatch is the only error boundary method defined logError(fiber, errorInfo); } var error = errorInfo.value; @@ -16172,12 +17989,19 @@ function throwException( // This is a thenable. var thenable = value; + checkForWrongSuspensePriorityInDEV(sourceFiber); + + 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) + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) ) { // Found the nearest boundary. @@ -16191,15 +18015,15 @@ function throwException( thenables.add(thenable); } - // If the boundary is outside of concurrent mode, we should *not* + // If the boundary is outside of batched 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 concurrent mode tree. If the Suspense is outside of it, we + // inside a batched mode tree. If the Suspense is outside of it, we // should *not* suspend the commit. - if ((_workInProgress.mode & ConcurrentMode) === NoContext) { + if ((_workInProgress.mode & BatchedMode) === NoMode) { _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete. @@ -16216,9 +18040,9 @@ function throwException( 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 updte to + // since it's known to be in an inconsistent state. Use a force update to // prevent a bail out. - var update = createUpdate(Sync); + var update = createUpdate(Sync, null); update.tag = ForceUpdate; enqueueUpdate(sourceFiber, update); } @@ -16234,11 +18058,51 @@ function throwException( // 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. SuspenseConfig applies 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. attachPingListener(root, renderExpirationTime, thenable); _workInProgress.effectTag |= ShouldCapture; _workInProgress.expirationTime = renderExpirationTime; + return; } else if ( enableSuspenseServerRenderer && @@ -16254,7 +18118,9 @@ function throwException( (function() { if (!current$$1) { throw ReactError( - "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React." + Error( + "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React." + ) ); } })(); @@ -16344,130 +18210,29 @@ function throwException( } while (workInProgress !== null); } -function unwindWork(workInProgress, renderExpirationTime) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; - if (isContextProvider(Component)) { - popContext(workInProgress); - } - var effectTag = workInProgress.effectTag; - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - return null; - } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; - (function() { - if (!((_effectTag & DidCapture) === NoEffect)) { - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - })(); - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; - } - case SuspenseComponent: { - var _effectTag2 = workInProgress.effectTag; - if (_effectTag2 & ShouldCapture) { - workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; - // Captured a suspense effect. Re-render the boundary. - return workInProgress; - } - return null; - } - case DehydratedSuspenseComponent: { - if (enableSuspenseServerRenderer) { - // TODO: popHydrationState - var _effectTag3 = workInProgress.effectTag; - if (_effectTag3 & ShouldCapture) { - workInProgress.effectTag = - (_effectTag3 & ~ShouldCapture) | DidCapture; - // Captured a suspense effect. Re-render the boundary. - return workInProgress; - } - } - return null; - } - case HostPortal: - popHostContainer(workInProgress); - return null; - case ContextProvider: - popProvider(workInProgress); - return null; - case EventComponent: - case EventTarget: - if (enableEventAPI) { - popHostContext(workInProgress); - } - return null; - default: - return null; - } -} - -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); - } - break; - } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - break; - } - case HostComponent: { - popHostContext(interruptedWork); - break; - } - case HostPortal: - popHostContainer(interruptedWork); - break; - case ContextProvider: - popProvider(interruptedWork); - break; - default: - break; - } -} - -// TODO: Ahaha Andrew is bad at spellling // DEV stuff var ceil = Math.ceil; var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; -var ReactShouldWarnActingUpdates = - ReactSharedInternals.ReactShouldWarnActingUpdates; +var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; -var NotWorking = 0; -var BatchedPhase = 1; -var LegacyUnbatchedPhase = 2; -var FlushSyncPhase = 3; -var RenderPhase = 4; -var CommitPhase = 5; +var NoContext = /* */ 0; +var BatchedContext = /* */ 1; +var EventContext = /* */ 2; +var DiscreteEventContext = /* */ 4; +var LegacyUnbatchedContext = /* */ 8; +var RenderContext = /* */ 16; +var CommitContext = /* */ 32; var RootIncomplete = 0; var RootErrored = 1; var RootSuspended = 2; -var RootCompleted = 3; +var RootSuspendedWithDelay = 3; +var RootCompleted = 4; -// The phase of work we're currently in -var workPhase = NotWorking; +// Describes where we are in the React execution stack +var executionContext = NoContext; // The root we're working on var workInProgressRoot = null; // The fiber we're working on @@ -16480,7 +18245,17 @@ var workInProgressRootExitStatus = RootIncomplete; // This is conceptually a time stamp but expressed in terms of an ExpirationTime // because we deal mostly with expiration times in the hot path, so this avoids // the conversion happening in the hot path. -var workInProgressRootMostRecentEventTime = Sync; +var workInProgressRootLatestProcessedExpirationTime = Sync; +var workInProgressRootLatestSuspenseTimeout = Sync; +var workInProgressRootCanSuspendUsingConfig = null; +// If we're pinged while rendering we don't always restart immediately. +// This flag determines if it might be worthwhile to restart if an opportunity +// happens latere. +var workInProgressRootHasPendingPing = false; +// 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; +var FALLBACK_THROTTLE_MS = 500; var nextEffect = null; var hasUncaughtError = false; @@ -16503,6 +18278,12 @@ var nestedPassiveUpdateCount = 0; var interruptedBy = null; +// Marks the need to reschedule pending interactions at these expiration times +// during the commit phase. This enables them to be traced across components +// that spawn new work during render. E.g. hidden boundaries, suspended SSR +// hydration or SuspenseList. +var spawnedWorkDuringRender = null; + // Expiration times are computed by adding to the current time (the start // time). However, if two updates are scheduled within the same event, we // should treat their start times as simultaneous, even if the actual clock @@ -16514,7 +18295,7 @@ var interruptedBy = null; var currentEventTime = NoWork; function requestCurrentTime() { - if (workPhase === RenderPhase || workPhase === CommitPhase) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { // We're inside React, so it's fine to read the actual time. return msToExpirationTime(now()); } @@ -16528,46 +18309,62 @@ function requestCurrentTime() { return currentEventTime; } -function computeExpirationForFiber(currentTime, fiber) { - if ((fiber.mode & ConcurrentMode) === NoContext) { +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + var mode = fiber.mode; + if ((mode & BatchedMode) === NoMode) { return Sync; } - if (workPhase === RenderPhase) { + var priorityLevel = getCurrentPriorityLevel(); + if ((mode & ConcurrentMode) === NoMode) { + return priorityLevel === ImmediatePriority ? Sync : Batched; + } + + if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering return renderExpirationTime; } - // Compute an expiration time based on the Scheduler priority. var expirationTime = void 0; - var priorityLevel = getCurrentPriorityLevel(); - switch (priorityLevel) { - case ImmediatePriority: - expirationTime = Sync; - break; - case UserBlockingPriority: - // TODO: Rename this to computeUserBlockingExpiration - expirationTime = computeInteractiveExpiration(currentTime); - break; - case NormalPriority: - case LowPriority: - // TODO: Handle LowPriority - // TODO: Rename this to... something better. - expirationTime = computeAsyncExpiration(currentTime); - break; - case IdlePriority: - expirationTime = Never; - break; - default: - (function() { - { - throw ReactError("Expected a valid priority level"); - } - })(); + if (suspenseConfig !== null) { + // Compute an expiration time based on the Suspense timeout. + expirationTime = computeSuspenseExpiration( + currentTime, + suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION + ); + } else { + // Compute an expiration time based on the Scheduler priority. + switch (priorityLevel) { + case ImmediatePriority: + expirationTime = Sync; + break; + case UserBlockingPriority: + // TODO: Rename this to computeUserBlockingExpiration + expirationTime = computeInteractiveExpiration(currentTime); + break; + case NormalPriority: + case LowPriority: + // TODO: Handle LowPriority + // TODO: Rename this to... something better. + expirationTime = computeAsyncExpiration(currentTime); + break; + case IdlePriority: + expirationTime = Never; + break; + default: + (function() { + { + throw ReactError(Error("Expected a valid priority level")); + } + })(); + } } // If we're in the middle of rendering a tree, do not update at the same // expiration time that is already rendering. + // TODO: We shouldn't have to do this if the update is on a different root. + // Refactor computeExpirationForFiber + scheduleUpdate so we have access to + // the root when we check for this condition. if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; @@ -16591,8 +18388,20 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { checkForInterruption(fiber, expirationTime); recordScheduleUpdate(); + // TODO: computeExpirationForFiber also reads the priority. Pass the + // priority as an argument to that function and this one. + var priorityLevel = getCurrentPriorityLevel(); + if (expirationTime === Sync) { - if (workPhase === LegacyUnbatchedPhase) { + if ( + // Check if we're inside unbatchedUpdates + (executionContext & LegacyUnbatchedContext) !== NoContext && + // Check if we're not already rendering + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + // Register pending interactions on the root to avoid losing traced interaction data. + schedulePendingInteractions(root, expirationTime); + // This is a legacy edge case. The initial mount of a ReactDOM.render-ed // root inside of batchedUpdates should be synchronous, but layout updates // should be deferred until the end of the batch. @@ -16602,35 +18411,36 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { } } else { scheduleCallbackForRoot(root, ImmediatePriority, Sync); - if (workPhase === NotWorking) { + if (executionContext === NoContext) { // Flush the synchronous work now, wnless we're already working or inside // a batch. This is intentionally inside scheduleUpdateOnFiber instead of // scheduleCallbackForFiber to preserve the ability to schedule a callback - // without immediately flushing it. We only do this for user-initated + // without immediately flushing it. We only do this for user-initiated // updates, to preserve historical behavior of sync mode. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } } else { - // TODO: computeExpirationForFiber also reads the priority. Pass the - // priority as an argument to that function and this one. - var priorityLevel = getCurrentPriorityLevel(); - if (priorityLevel === UserBlockingPriority) { - // This is the result of a discrete event. Track the lowest priority - // discrete update per root so we can flush them early, if needed. - if (rootsWithPendingDiscreteUpdates === null) { - rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); - } else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); - if ( - lastDiscreteTime === undefined || - lastDiscreteTime > expirationTime - ) { - rootsWithPendingDiscreteUpdates.set(root, expirationTime); - } + scheduleCallbackForRoot(root, priorityLevel, expirationTime); + } + + if ( + (executionContext & DiscreteEventContext) !== NoContext && + // Only updates at user-blocking priority or greater are considered + // discrete, even inside a discrete event. + (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. + if (rootsWithPendingDiscreteUpdates === null) { + rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); + } else { + var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); + if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) { + rootsWithPendingDiscreteUpdates.set(root, expirationTime); } } - scheduleCallbackForRoot(root, priorityLevel, expirationTime); } } var scheduleWork = scheduleUpdateOnFiber; @@ -16711,42 +18521,46 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { } root.callbackExpirationTime = expirationTime; - var options = null; - if (expirationTime !== Sync && expirationTime !== Never) { - var timeout = expirationTimeToMs(expirationTime) - now(); - if (timeout > 5000) { - // Sanity check. Should never take longer than 5 seconds. - // TODO: Add internal warning? - timeout = 5000; + if (expirationTime === Sync) { + // Sync React callbacks are scheduled on a special internal queue + root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + ); + } else { + var options = null; + if (expirationTime !== Never) { + var timeout = expirationTimeToMs(expirationTime) - now(); + options = { timeout: timeout }; + } + + root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + options + ); + if ( + enableUserTimingAPI && + expirationTime !== Sync && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + // Scheduled an async callback, and we're not already working. Add an + // entry to the flamegraph that shows we're waiting for a callback + // to fire. + startRequestCallbackTimer(); } - options = { timeout: timeout }; - } - - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - options - ); - if ( - enableUserTimingAPI && - expirationTime !== Sync && - workPhase !== RenderPhase && - workPhase !== CommitPhase - ) { - // Scheduled an async callback, and we're not already working. Add an - // entry to the flamegraph that shows we're waiting for a callback - // to fire. - startRequestCallbackTimer(); } } - // Add the current set of interactions to the pending set associated with - // this root. - schedulePendingInteraction(root, expirationTime); + // Associate the current interactions with this new root+priority. + schedulePendingInteractions(root, expirationTime); } function runRootCallback(root, callback, isSync) { @@ -16771,15 +18585,33 @@ function runRootCallback(root, callback, isSync) { } } -function flushInteractiveUpdates$1() { - if (workPhase === RenderPhase || workPhase === CommitPhase) { - // Can't synchronously flush interactive updates if React is already - // working. This is currently a no-op. - // TODO: Should we fire a warning? This happens if you synchronously invoke - // an input event inside an effect, like with `element.click()`. +function flushDiscreteUpdates() { + // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. + // However, `act` uses `batchedUpdates`, so there's no way to distinguish + // those two cases. Need to fix this before exposing flushDiscreteUpdates + // as a public API. + if ( + (executionContext & (BatchedContext | RenderContext | CommitContext)) !== + NoContext + ) { + if (true && (executionContext & RenderContext) !== NoContext) { + warning$1( + false, + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } + // We're already rendering, so we can't synchronously flush pending work. + // This is probably a nested event dispatch triggered by a lifecycle/effect, + // like `el.focus()`. Exit. return; } flushPendingDiscreteUpdates(); + if (!revertPassiveEffectsChange) { + // If the discrete updates scheduled passive effects, flush them now so that + // they fire before the next serial event. + flushPassiveEffects(); + } } function resolveLocksOnRoot(root, expirationTime) { @@ -16789,8 +18621,6 @@ function resolveLocksOnRoot(root, expirationTime) { firstBatch._defer && firstBatch._expirationTime >= expirationTime ) { - root.finishedWork = root.current.alternate; - root.pendingCommitExpirationTime = expirationTime; scheduleCallback(NormalPriority, function() { firstBatch._onComplete(); return null; @@ -16801,15 +18631,6 @@ function resolveLocksOnRoot(root, expirationTime) { } } -function interactiveUpdates$1(fn, a, b, c) { - if (workPhase === NotWorking) { - // TODO: Remove this call. Instead of doing this automatically, the caller - // should explicitly call flushInteractiveUpdates. - flushPendingDiscreteUpdates(); - } - return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); -} - function flushPendingDiscreteUpdates() { if (rootsWithPendingDiscreteUpdates !== null) { // For each root with pending discrete updates, schedule a callback to @@ -16817,56 +18638,84 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback( - ImmediatePriority, - renderRoot.bind(null, root, expirationTime) - ); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); // Now flush the immediate queue. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function batchedUpdates$1(fn, a) { - if (workPhase !== NotWorking) { - // We're already working, or inside a batch, so batchedUpdates is a no-op. + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + try { return fn(a); + } finally { + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } } - workPhase = BatchedPhase; +} + +function batchedEventUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= EventContext; try { return fn(a); } finally { - workPhase = NotWorking; - // Flush the immediate callbacks that were scheduled during this batch - flushImmediateQueue(); + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} + +function discreteUpdates$1(fn, a, b, c) { + var prevExecutionContext = executionContext; + executionContext |= DiscreteEventContext; + try { + // Should this + return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); + } finally { + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } } } function flushSync(fn, a) { - if (workPhase === RenderPhase || workPhase === CommitPhase) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { (function() { { throw ReactError( - "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." + Error( + "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." + ) ); } })(); } - var prevWorkPhase = workPhase; - workPhase = FlushSyncPhase; + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; try { return runWithPriority(ImmediatePriority, fn.bind(null, a)); } finally { - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up // the stack. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = NoWork; + root.finishedWork = null; + root.finishedExpirationTime = NoWork; var timeoutHandle = root.timeoutHandle; if (timeoutHandle !== noTimeout) { @@ -16888,17 +18737,26 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = Sync; + workInProgressRootLatestProcessedExpirationTime = Sync; + workInProgressRootLatestSuspenseTimeout = Sync; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = false; + + if (enableSchedulerTracing) { + spawnedWorkDuringRender = null; + } { ReactStrictModeWarnings.discardPendingWarnings(); + componentsThatSuspendedAtHighPri = null; + componentsThatTriggeredHighPriSuspend = null; } } function renderRoot(root, expirationTime, isSync) { (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Should not already be working."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError(Error("Should not already be working.")); } })(); @@ -16914,10 +18772,11 @@ function renderRoot(root, expirationTime, isSync) { return null; } - if (root.pendingCommitExpirationTime === expirationTime) { + if (isSync && root.finishedExpirationTime === expirationTime) { // There's already a pending commit at this expiration time. - root.pendingCommitExpirationTime = NoWork; - return commitRoot.bind(null, root, expirationTime); + // TODO: This is poorly factored. This case only exists for the + // batch.commit() API. + return commitRoot.bind(null, root); } flushPassiveEffects(); @@ -16926,14 +18785,34 @@ function renderRoot(root, expirationTime, isSync) { // and prepare a fresh one. Otherwise we'll continue where we left off. if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) { prepareFreshStack(root, expirationTime); - startWorkOnPendingInteraction(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) { + // We could've received an update at a lower priority while we yielded. + // We're suspended in a delayed state. Once we complete this render we're + // just going to try to recover at the last pending time anyway so we might + // as well start doing that eagerly. + // Ideally we should be able to do this even for retries but we don't yet + // know if we're going to process an update which wants to commit earlier, + // and this path happens very early so it would happen too often. Instead, + // for that case, we'll wait until we complete. + if (workInProgressRootHasPendingPing) { + // We have a ping at this expiration. Let's restart to see if we get unblocked. + prepareFreshStack(root, expirationTime); + } else { + var lastPendingTime = root.lastPendingTime; + if (lastPendingTime < expirationTime) { + // There's lower priority work. It might be unsuspended. Try rendering + // at that level immediately, while preserving the position in the queue. + return renderRoot.bind(null, root, lastPendingTime); + } + } } // If we have a work-in-progress fiber, it means there's still work to do // in this root. if (workInProgress !== null) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + var prevExecutionContext = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -16959,8 +18838,8 @@ function renderRoot(root, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) { // Restart at the current time. - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = prevExecutionContext; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; @@ -16984,7 +18863,7 @@ function renderRoot(root, expirationTime, isSync) { break; } catch (thrownValue) { // Reset module-level state that was set during the render phase. - resetContextDependences(); + resetContextDependencies(); resetHooks(); var sourceFiber = workInProgress; @@ -16994,7 +18873,7 @@ function renderRoot(root, expirationTime, isSync) { // supposed to capture all errors that weren't caught by an error // boundary. prepareFreshStack(root, expirationTime); - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; throw thrownValue; } @@ -17017,8 +18896,8 @@ function renderRoot(root, expirationTime, isSync) { } } while (true); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = prevExecutionContext; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; @@ -17038,6 +18917,9 @@ function renderRoot(root, expirationTime, isSync) { // something suspended, wait to commit it after a timeout. stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + var isLocked = resolveLocksOnRoot(root, expirationTime); if (isLocked) { // This root has a lock that prevents it from committing. Exit. If we begin @@ -17049,11 +18931,13 @@ function renderRoot(root, expirationTime, isSync) { // Set this to null to indicate there's no in-progress render. workInProgressRoot = null; + flushSuspensePriorityWarningInDEV(); + switch (workInProgressRootExitStatus) { case RootIncomplete: { (function() { { - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); } })(); } @@ -17063,77 +18947,192 @@ function renderRoot(root, expirationTime, isSync) { case RootErrored: { // An error was thrown. First check if there is lower priority work // scheduled on this root. - var lastPendingTime = root.lastPendingTime; - if (root.lastPendingTime < expirationTime) { + var _lastPendingTime = root.lastPendingTime; + if (_lastPendingTime < expirationTime) { // There's lower priority work. Before raising the error, try rendering // at the lower priority to see if it fixes it. Use a continuation to // maintain the existing priority and position in the queue. - return renderRoot.bind(null, root, lastPendingTime); + return renderRoot.bind(null, root, _lastPendingTime); } if (!isSync) { // If we're rendering asynchronously, it's possible the error was // caused by tearing due to a mutation during an event. Try rendering // one more time without yiedling to events. prepareFreshStack(root, expirationTime); - scheduleCallback( - ImmediatePriority, - renderRoot.bind(null, root, expirationTime) - ); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); return null; } // If we're already rendering synchronously, commit the root in its // errored state. - return commitRoot.bind(null, root, expirationTime); + return commitRoot.bind(null, root); } case RootSuspended: { + // We have an acceptable loading state. We need to figure out if we should + // immediately commit it or wait a bit. + + // If we have processed new updates during this render, we may now have a + // new loading state ready. We want to ensure that we commit that as soon as + // possible. + var hasNotProcessedNewUpdates = + workInProgressRootLatestProcessedExpirationTime === Sync; + if (hasNotProcessedNewUpdates && !isSync) { + // If we have not processed any new updates during this pass, then this is + // either a retry of an existing fallback state or a hidden tree. + // Hidden trees shouldn't be batched with other work and after that's + // fixed it can only be a retry. + // We're going to throttle committing retries so that we don't show too + // many loading states too quickly. + var msUntilTimeout = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); + // Don't bother with a very short suspense time. + if (msUntilTimeout > 10) { + if (workInProgressRootHasPendingPing) { + // This render was pinged but we didn't get to restart earlier so try + // restarting now instead. + prepareFreshStack(root, expirationTime); + return renderRoot.bind(null, root, expirationTime); + } + var _lastPendingTime2 = root.lastPendingTime; + if (_lastPendingTime2 < expirationTime) { + // There's lower priority work. It might be unsuspended. Try rendering + // at that level. + return renderRoot.bind(null, root, _lastPendingTime2); + } + // The render is suspended, it hasn't timed out, and there's no lower + // priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + msUntilTimeout + ); + return null; + } + } + // The work expired. Commit immediately. + return commitRoot.bind(null, root); + } + case RootSuspendedWithDelay: { if (!isSync) { - var _lastPendingTime = root.lastPendingTime; - if (root.lastPendingTime < expirationTime) { + // We're suspended in a state that should be avoided. We'll try to avoid committing + // it for as long as the timeouts let us. + if (workInProgressRootHasPendingPing) { + // This render was pinged but we didn't get to restart earlier so try + // restarting now instead. + prepareFreshStack(root, expirationTime); + return renderRoot.bind(null, root, expirationTime); + } + var _lastPendingTime3 = root.lastPendingTime; + if (_lastPendingTime3 < expirationTime) { // There's lower priority work. It might be unsuspended. Try rendering - // at that level. - return renderRoot.bind(null, root, _lastPendingTime); + // at that level immediately. + return renderRoot.bind(null, root, _lastPendingTime3); } - // If workInProgressRootMostRecentEventTime is Sync, that means we didn't - // track any event times. That can happen if we retried but nothing switched - // from fallback to content. There's no reason to delay doing no work. - if (workInProgressRootMostRecentEventTime !== Sync) { - var msUntilTimeout = computeMsUntilTimeout( - workInProgressRootMostRecentEventTime, - expirationTime + + var _msUntilTimeout = void 0; + if (workInProgressRootLatestSuspenseTimeout !== Sync) { + // We have processed a suspense config whose expiration time we can use as + // the timeout. + _msUntilTimeout = + expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now(); + } else if (workInProgressRootLatestProcessedExpirationTime === Sync) { + // This should never normally happen because only new updates cause + // delayed states, so we should have processed something. However, + // this could also happen in an offscreen tree. + _msUntilTimeout = 0; + } else { + // If we don't have a suspense config, we're going to use a heuristic to + var eventTimeMs = inferTimeFromExpirationTime( + workInProgressRootLatestProcessedExpirationTime ); - // Don't bother with a very short suspense time. - if (msUntilTimeout > 10) { - // The render is suspended, it hasn't timed out, and there's no lower - // priority work to do. Instead of committing the fallback - // immediately, wait for more data to arrive. - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, expirationTime), - msUntilTimeout - ); - return null; + var currentTimeMs = now(); + var timeUntilExpirationMs = + expirationTimeToMs(expirationTime) - currentTimeMs; + var timeElapsed = currentTimeMs - eventTimeMs; + if (timeElapsed < 0) { + // We get this wrong some time since we estimate the time. + timeElapsed = 0; + } + + _msUntilTimeout = jnd(timeElapsed) - timeElapsed; + + // Clamp the timeout to the expiration time. + // TODO: Once the event time is exact instead of inferred from expiration time + // we don't need this. + if (timeUntilExpirationMs < _msUntilTimeout) { + _msUntilTimeout = timeUntilExpirationMs; } } + + // Don't bother with a very short suspense time. + if (_msUntilTimeout > 10) { + // The render is suspended, it hasn't timed out, and there's no lower + // priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + _msUntilTimeout + ); + return null; + } } // The work expired. Commit immediately. - return commitRoot.bind(null, root, expirationTime); + return commitRoot.bind(null, root); } case RootCompleted: { // The work completed. Ready to commit. - return commitRoot.bind(null, root, expirationTime); + if ( + !isSync && + workInProgressRootLatestProcessedExpirationTime !== Sync && + workInProgressRootCanSuspendUsingConfig !== null + ) { + // If we have exceeded the minimum loading delay, which probably + // means we have shown a spinner already, we might have to suspend + // a bit longer to ensure that the spinner is shown for enough time. + var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay( + workInProgressRootLatestProcessedExpirationTime, + expirationTime, + workInProgressRootCanSuspendUsingConfig + ); + if (_msUntilTimeout2 > 10) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + _msUntilTimeout2 + ); + return null; + } + } + return commitRoot.bind(null, root); } default: { (function() { { - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } })(); } } } -function markRenderEventTime(expirationTime) { - if (expirationTime < workInProgressRootMostRecentEventTime) { - workInProgressRootMostRecentEventTime = expirationTime; +function markCommitTimeOfFallback() { + globalMostRecentFallbackTime = now(); +} + +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + if ( + expirationTime < workInProgressRootLatestProcessedExpirationTime && + expirationTime > Never + ) { + workInProgressRootLatestProcessedExpirationTime = expirationTime; + } + if (suspenseConfig !== null) { + if ( + expirationTime < workInProgressRootLatestSuspenseTimeout && + expirationTime > Never + ) { + workInProgressRootLatestSuspenseTimeout = expirationTime; + // Most of the time we only have one config and getting wrong is not bad. + workInProgressRootCanSuspendUsingConfig = suspenseConfig; + } } } @@ -17143,15 +19142,29 @@ function renderDidSuspend() { } } -function renderDidError() { +function renderDidSuspendDelayIfPossible() { if ( workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended ) { + workInProgressRootExitStatus = RootSuspendedWithDelay; + } +} + +function renderDidError() { + if (workInProgressRootExitStatus !== RootCompleted) { workInProgressRootExitStatus = RootErrored; } } +// Called during render to determine if anything has suspended. +// Returns false if we're not sure. +function renderHasNotSuspendedYet() { + // If something errored or completed, we can't really be sure, + // so those are false. + return workInProgressRootExitStatus === RootIncomplete; +} + function inferTimeFromExpirationTime(expirationTime) { // We don't know exactly when the update was scheduled, but we can infer an // approximate start time from the expiration time. @@ -17159,6 +19172,20 @@ function inferTimeFromExpirationTime(expirationTime) { return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION; } +function inferTimeFromExpirationTimeWithSuspenseConfig( + expirationTime, + suspenseConfig +) { + // We don't know exactly when the update was scheduled, but we can infer an + // approximate start time from the expiration time by subtracting the timeout + // that was added to the event time. + var earliestExpirationTimeMs = expirationTimeToMs(expirationTime); + return ( + earliestExpirationTimeMs - + (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) + ); +} + function workLoopSync() { // Already timed out, so perform work without checking if we need to yield. while (workInProgress !== null) { @@ -17183,7 +19210,7 @@ function performUnitOfWork(unitOfWork) { setCurrentFiber(unitOfWork); var next = void 0; - if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoContext) { + if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); @@ -17219,7 +19246,7 @@ function completeUnitOfWork(unitOfWork) { var next = void 0; if ( !enableProfilerTimer || - (workInProgress.mode & ProfileMode) === NoContext + (workInProgress.mode & ProfileMode) === NoMode ) { next = completeWork(current$$1, workInProgress, renderExpirationTime); } else { @@ -17285,7 +19312,7 @@ function completeUnitOfWork(unitOfWork) { if ( enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoContext + (workInProgress.mode & ProfileMode) !== NoMode ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); @@ -17349,7 +19376,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoContext) { + if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -17402,11 +19429,8 @@ function resetChildExpirationTime(completedWork) { completedWork.childExpirationTime = newChildExpirationTime; } -function commitRoot(root, expirationTime) { - runWithPriority( - ImmediatePriority, - commitRootImpl.bind(null, root, expirationTime) - ); +function commitRoot(root) { + runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root)); // If there are passive effects, schedule a callback to flush them. This goes // outside commitRootImpl so that it inherits the priority of the render. if (rootWithPendingPassiveEffects !== null) { @@ -17419,19 +19443,31 @@ function commitRoot(root, expirationTime) { return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); flushRenderPhaseStrictModeWarningsInDEV(); (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Should not already be working."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError(Error("Should not already be working.")); } })(); - var finishedWork = root.current.alternate; + + var finishedWork = root.finishedWork; + var expirationTime = root.finishedExpirationTime; + if (finishedWork === null) { + return null; + } + root.finishedWork = null; + root.finishedExpirationTime = NoWork; + (function() { - if (!(finishedWork !== null)) { - throw ReactError("Should have a work-in-progress root."); + if (!(finishedWork !== root.current)) { + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); } })(); @@ -17487,8 +19523,8 @@ function commitRootImpl(root, expirationTime) { } if (firstEffect !== null) { - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + var prevExecutionContext = executionContext; + executionContext |= CommitContext; var prevInteractions = null; if (enableSchedulerTracing) { prevInteractions = tracing.__interactionsRef.current; @@ -17514,7 +19550,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var error = clearCaughtError(); @@ -17540,7 +19576,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var _error = clearCaughtError(); @@ -17575,7 +19611,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var _error2 = clearCaughtError(); @@ -17588,10 +19624,14 @@ function commitRootImpl(root, expirationTime) { nextEffect = null; + // Tell Scheduler to yield at the end of the frame, so the browser has an + // opportunity to paint. + requestPaint(); + if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; } - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; } else { // No effects. root.current = finishedWork; @@ -17611,6 +19651,8 @@ function commitRootImpl(root, expirationTime) { stopCommitTimer(); + var rootDidHavePassiveEffects = rootDoesHavePassiveEffects; + if (rootDoesHavePassiveEffects) { // This commit has passive effects. Stash a reference to them. But don't // schedule a callback until after flushing layout work. @@ -17618,11 +19660,14 @@ function commitRootImpl(root, expirationTime) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsExpirationTime = expirationTime; } else { - if (enableSchedulerTracing) { - // If there are no passive effects, then we can complete the pending - // interactions. Otherwise, we'll wait until after the passive effects - // are flushed. - finishPendingInteractions(root, expirationTime); + // 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; + nextEffect = nextNextEffect; } } @@ -17634,6 +19679,21 @@ function commitRootImpl(root, expirationTime) { currentTime, remainingExpirationTime ); + + if (enableSchedulerTracing) { + if (spawnedWorkDuringRender !== null) { + var expirationTimes = spawnedWorkDuringRender; + spawnedWorkDuringRender = null; + for (var i = 0; i < expirationTimes.length; i++) { + scheduleInteractions( + root, + expirationTimes[i], + root.memoizedInteractions + ); + } + } + } + scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime); } else { // If there's no remaining work, we can clear the set of already failed @@ -17641,7 +19701,17 @@ function commitRootImpl(root, expirationTime) { legacyErrorBoundariesThatAlreadyFailed = null; } - onCommitRoot(finishedWork.stateNode); + if (enableSchedulerTracing) { + if (!rootDidHavePassiveEffects) { + // If there are no passive effects, then we can complete the pending interactions. + // Otherwise, we'll wait until after the passive effects are flushed. + // Wait to do this until after remaining work has been scheduled, + // so that we don't prematurely signal complete for interactions when there's e.g. hidden work. + finishPendingInteractions(root, expirationTime); + } + } + + onCommitRoot(finishedWork.stateNode, expirationTime); if (remainingExpirationTime === Sync) { // Count the number of times the root synchronously re-renders without @@ -17663,7 +19733,7 @@ function commitRootImpl(root, expirationTime) { throw _error3; } - if (workPhase === LegacyUnbatchedPhase) { + if ((executionContext & LegacyUnbatchedContext) !== NoContext) { // This is a legacy edge case. We just committed the initial mount of // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired // synchronously, but layout updates should be deferred until the end @@ -17672,7 +19742,7 @@ function commitRootImpl(root, expirationTime) { } // If layout work was scheduled, flush it now. - flushImmediateQueue(); + flushSyncCallbackQueue(); return null; } @@ -17798,12 +19868,14 @@ function flushPassiveEffects() { } (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Cannot flush passive effects while already rendering."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); } })(); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + var prevExecutionContext = executionContext; + executionContext |= CommitContext; // 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 @@ -17816,7 +19888,7 @@ function flushPassiveEffects() { if (hasCaughtError()) { (function() { if (!(effect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var error = clearCaughtError(); @@ -17824,7 +19896,10 @@ function flushPassiveEffects() { } resetCurrentFiber(); } - effect = effect.nextEffect; + var nextNextEffect = effect.nextEffect; + // Remove nextEffect pointer to assist GC + effect.nextEffect = null; + effect = nextNextEffect; } if (enableSchedulerTracing) { @@ -17832,8 +19907,8 @@ function flushPassiveEffects() { finishPendingInteractions(root, expirationTime); } - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. @@ -17926,9 +20001,32 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { // Received a ping at the same priority level at which we're currently - // rendering. Restart from the root. Don't need to schedule a ping because - // we're already working on this tree. - prepareFreshStack(root, renderExpirationTime); + // rendering. We might want to restart this render. This should mirror + // the logic of whether or not a root suspends once it completes. + + // TODO: If we're rendering sync either due to Sync, Batched or expired, + // we should probably never restart. + + // If we're suspended with delay, we'll always suspend so we can always + // restart. If we're suspended without any updates, it might be a retry. + // If it's early in the retry we can restart. We can't know for sure + // whether we'll eventually process an update during this render pass, + // but it's somewhat unlikely that we get to a ping before that, since + // getting to the root most update is usually very fast. + if ( + workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + workInProgressRootLatestProcessedExpirationTime === Sync && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ) { + // Restart from the root. Don't need to schedule a ping because + // we're already working on this tree. + prepareFreshStack(root, renderExpirationTime); + } else { + // Even though we can't restart right now, we might get an + // opportunity later. So we mark this render as having a ping. + workInProgressRootHasPendingPing = true; + } return; } @@ -17947,6 +20045,12 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { // Mark the time at which this ping was scheduled. root.pingTime = suspendedTime; + if (root.finishedExpirationTime === suspendedTime) { + // If there's a pending fallback waiting to commit, throw it away. + root.finishedExpirationTime = NoWork; + root.finishedWork = null; + } + var currentTime = requestCurrentTime(); var priorityLevel = inferPriorityFromExpirationTime( currentTime, @@ -17956,12 +20060,17 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { } function retryTimedOutBoundary(boundaryFiber) { - // The boundary fiber (a Suspense component) previously timed out and was - // rendered in its fallback state. One of the promises that suspended it has - // resolved, which means at least part of the tree was likely unblocked. Try - // rendering again, at a new expiration time. + // The boundary fiber (a Suspense component or SuspenseList component) + // previously was rendered in its fallback state. One of the promises that + // suspended it has resolved, which means at least part of the tree was + // likely unblocked. Try rendering again, at a new expiration time. var currentTime = requestCurrentTime(); - var retryTime = computeExpirationForFiber(currentTime, boundaryFiber); + var suspenseConfig = null; // Retries don't carry over the already committed update. + var retryTime = computeExpirationForFiber( + currentTime, + boundaryFiber, + suspenseConfig + ); // TODO: Special case idle priority? var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime); var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime); @@ -17984,7 +20093,9 @@ function resolveRetryThenable(boundaryFiber, thenable) { (function() { { throw ReactError( - "Pinged unknown suspense boundary type. This is probably a bug in React." + Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ) ); } })(); @@ -18027,29 +20138,30 @@ function jnd(timeElapsed) { : ceil(timeElapsed / 1960) * 1960; } -function computeMsUntilTimeout(mostRecentEventTime, committedExpirationTime) { - if (disableYielding) { - // Timeout immediately when yielding is disabled. +function computeMsUntilSuspenseLoadingDelay( + mostRecentEventTime, + committedExpirationTime, + suspenseConfig +) { + var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0; + if (busyMinDurationMs <= 0) { return 0; } + var busyDelayMs = suspenseConfig.busyDelayMs | 0; - var eventTimeMs = inferTimeFromExpirationTime(mostRecentEventTime); + // Compute the time until this render pass would expire. var currentTimeMs = now(); + var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig( + mostRecentEventTime, + suspenseConfig + ); var timeElapsed = currentTimeMs - eventTimeMs; - - var msUntilTimeout = jnd(timeElapsed) - timeElapsed; - - // Compute the time until this render pass would expire. - var timeUntilExpirationMs = - expirationTimeToMs(committedExpirationTime) - currentTimeMs; - - // Clamp the timeout to the expiration time. - // TODO: Once the event time is exact instead of inferred from expiration time - // we don't need this. - if (timeUntilExpirationMs < msUntilTimeout) { - msUntilTimeout = timeUntilExpirationMs; + if (timeElapsed <= busyDelayMs) { + // If we haven't yet waited longer than the initial delay, we don't + // have to wait any additional time. + return 0; } - + var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`. return msUntilTimeout; } @@ -18061,7 +20173,9 @@ function checkForNestedUpdates() { (function() { { throw ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) ); } })(); @@ -18083,11 +20197,10 @@ function checkForNestedUpdates() { function flushRenderPhaseStrictModeWarningsInDEV() { { - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); ReactStrictModeWarnings.flushLegacyContextWarning(); if (warnAboutDeprecatedLifecycles) { - ReactStrictModeWarnings.flushPendingDeprecationWarnings(); + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } } @@ -18182,7 +20295,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // Keep this code in sync with renderRoot; any changes here must have // corresponding changes there. - resetContextDependences(); + resetContextDependencies(); resetHooks(); // Unwind the failed stack frame @@ -18247,585 +20360,509 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { "within `render`). Render methods should be a pure function of " + "props and state." ); - didWarnAboutUpdateInRender = true; - break; - } - } - } -} - -function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { - { - if ( - workPhase === NotWorking && - ReactShouldWarnActingUpdates.current === false - ) { - warningWithoutStack$1( - false, - "An update to %s inside a test was not wrapped in act(...).\n\n" + - "When testing, code that causes React state updates should be " + - "wrapped into act(...):\n\n" + - "act(() => {\n" + - " /* fire events that update state */\n" + - "});\n" + - "/* assert on the output */\n\n" + - "This ensures that you're testing the behavior the user would see " + - "in the browser." + - " Learn more at https://fb.me/react-wrap-tests-with-act" + - "%s", - getComponentName(fiber.type), - getStackByFiberInDevAndProd(fiber) - ); - } - } -} - -var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; - -function computeThreadID(root, expirationTime) { - // Interaction threads are unique per root and expiration time. - return expirationTime * 1000 + root.interactionThreadID; -} - -function schedulePendingInteraction(root, expirationTime) { - // This is called when work is scheduled on a root. It sets up a pending - // interaction, which is completed once the work commits. - if (!enableSchedulerTracing) { - return; - } - - var interactions = tracing.__interactionsRef.current; - if (interactions.size > 0) { - var pendingInteractionMap = root.pendingInteractionMap; - var pendingInteractions = pendingInteractionMap.get(expirationTime); - if (pendingInteractions != null) { - interactions.forEach(function(interaction) { - if (!pendingInteractions.has(interaction)) { - // Update the pending async work count for previously unscheduled interaction. - interaction.__count++; - } - - pendingInteractions.add(interaction); - }); - } else { - pendingInteractionMap.set(expirationTime, new Set(interactions)); - - // Update the pending async work count for the current interactions. - interactions.forEach(function(interaction) { - interaction.__count++; - }); - } - - var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { - var threadID = computeThreadID(root, expirationTime); - subscriber.onWorkScheduled(interactions, threadID); - } - } -} - -function startWorkOnPendingInteraction(root, expirationTime) { - // This is called when new work is started on a root. - if (!enableSchedulerTracing) { - return; - } - - // Determine which interactions this batch of work currently includes, So that - // we can accurately attribute time spent working on it, And so that cascading - // work triggered during the render phase will be associated with it. - var interactions = new Set(); - root.pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledExpirationTime - ) { - if (scheduledExpirationTime >= expirationTime) { - scheduledInteractions.forEach(function(interaction) { - return interactions.add(interaction); - }); - } - }); - - // Store the current set of interactions on the FiberRoot for a few reasons: - // We can re-use it in hot functions like renderRoot() without having to - // recalculate it. We will also use it in commitWork() to pass to any Profiler - // onRender() hooks. This also provides DevTools with a way to access it when - // the onCommitRoot() hook is called. - root.memoizedInteractions = interactions; - - if (interactions.size > 0) { - var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { - var threadID = computeThreadID(root, expirationTime); - try { - subscriber.onWorkStarted(interactions, threadID); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); + didWarnAboutUpdateInRender = true; + break; } } } } -function finishPendingInteractions(root, committedExpirationTime) { - if (!enableSchedulerTracing) { - return; - } - - var earliestRemainingTimeAfterCommit = root.firstPendingTime; - - var subscriber = void 0; +var IsThisRendererActing = { current: false }; - try { - subscriber = tracing.__subscriberRef.current; - if (subscriber !== null && root.memoizedInteractions.size > 0) { - var threadID = computeThreadID(root, committedExpirationTime); - subscriber.onWorkStopped(root.memoizedInteractions, threadID); - } - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } finally { - // Clear completed interactions from the pending Map. - // Unless the render was suspended or cascading work was scheduled, - // In which case– leave pending interactions until the subsequent render. - var pendingInteractionMap = root.pendingInteractionMap; - pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledExpirationTime +function warnIfNotScopedWithMatchingAct(fiber) { + { + if ( + warnsIfNotActing === true && + IsSomeRendererActing.current === true && + IsThisRendererActing.current !== true ) { - // Only decrement the pending interaction count if we're done. - // If there's still work at the current priority, - // That indicates that we are waiting for suspense data. - if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { - pendingInteractionMap.delete(scheduledExpirationTime); - - scheduledInteractions.forEach(function(interaction) { - interaction.__count--; - - if (subscriber !== null && interaction.__count === 0) { - try { - subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } - } - }); - } - }); + warningWithoutStack$1( + false, + "It looks like you're using the wrong act() around your test interactions.\n" + + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + + "// for react-dom:\n" + + "import {act} from 'react-dom/test-utils';\n" + + "//...\n" + + "act(() => ...);\n\n" + + "// for react-test-renderer:\n" + + "import TestRenderer from 'react-test-renderer';\n" + + "const {act} = TestRenderer;\n" + + "//...\n" + + "act(() => ...);" + + "%s", + getStackByFiberInDevAndProd(fiber) + ); + } } } -// Resolves type to a family. - -// Used by React Refresh runtime through DevTools Global Hook. - -var resolveFamily = null; -// $FlowFixMe Flow gets confused by a WeakSet feature check below. -var failedBoundaries = null; - -var setRefreshHandler = function(handler) { +function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { - resolveFamily = handler; + if ( + warnsIfNotActing === true && + (fiber.mode & StrictMode) !== NoMode && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); + } } -}; +} -function resolveFunctionForHotReloading(type) { +function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return type; - } - var family = resolveFamily(type); - if (family === undefined) { - return type; + if ( + warnsIfNotActing === true && + executionContext === NoContext && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s inside a test was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); } - // Use the latest known implementation. - return family.current; } } -function resolveClassForHotReloading(type) { - // No implementation differences. - return resolveFunctionForHotReloading(type); -} +var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; -function resolveForwardRefForHotReloading(type) { +var componentsThatSuspendedAtHighPri = null; +var componentsThatTriggeredHighPriSuspend = null; +function checkForWrongSuspensePriorityInDEV(sourceFiber) { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return type; - } - var family = resolveFamily(type); - if (family === undefined) { - // Check if we're dealing with a real forwardRef. Don't want to crash early. - if ( - type !== null && - type !== undefined && - typeof type.render === "function" - ) { - // ForwardRef is special because its resolved .type is an object, - // but it's possible that we only have its inner render function in the map. - // If that inner render function is different, we'll build a new forwardRef type. - var currentRender = resolveFunctionForHotReloading(type.render); - if (type.render !== currentRender) { - var syntheticType = { - $$typeof: REACT_FORWARD_REF_TYPE, - render: currentRender - }; - if (type.displayName !== undefined) { - syntheticType.displayName = type.displayName; + var currentPriorityLevel = getCurrentPriorityLevel(); + if ( + (sourceFiber.mode & ConcurrentMode) !== NoEffect && + (currentPriorityLevel === UserBlockingPriority || + currentPriorityLevel === ImmediatePriority) + ) { + var workInProgressNode = sourceFiber; + while (workInProgressNode !== null) { + // Add the component that triggered the suspense + var current$$1 = workInProgressNode.alternate; + if (current$$1 !== null) { + // TODO: warn component that triggers the high priority + // suspend is the HostRoot + switch (workInProgressNode.tag) { + case ClassComponent: + // Loop through the component's update queue and see whether the component + // has triggered any high priority updates + var updateQueue = current$$1.updateQueue; + if (updateQueue !== null) { + var update = updateQueue.firstUpdate; + while (update !== null) { + var priorityLevel = update.priority; + if ( + priorityLevel === UserBlockingPriority || + priorityLevel === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + break; + } + update = update.next; + } + } + break; + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if ( + workInProgressNode.memoizedState !== null && + workInProgressNode.memoizedState.baseUpdate !== null + ) { + var _update = workInProgressNode.memoizedState.baseUpdate; + // Loop through the functional component's memoized state to see whether + // the component has triggered any high pri updates + while (_update !== null) { + var priority = _update.priority; + if ( + priority === UserBlockingPriority || + priority === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + break; + } + if ( + _update.next === workInProgressNode.memoizedState.baseUpdate + ) { + break; + } + _update = _update.next; + } + } + break; + default: + break; } - return syntheticType; } + workInProgressNode = workInProgressNode.return; + } + + // Add the component name to a set. + var componentName = getComponentName(sourceFiber.type); + if (componentsThatSuspendedAtHighPri === null) { + componentsThatSuspendedAtHighPri = new Set([componentName]); + } else { + componentsThatSuspendedAtHighPri.add(componentName); } - return type; } - // Use the latest known implementation. - return family.current; } } -function isCompatibleFamilyForHotReloading(fiber, element) { +function flushSuspensePriorityWarningInDEV() { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return false; + if (componentsThatSuspendedAtHighPri !== null) { + var componentNames = []; + componentsThatSuspendedAtHighPri.forEach(function(name) { + componentNames.push(name); + }); + componentsThatSuspendedAtHighPri = null; + + var componentsThatTriggeredSuspendNames = []; + if (componentsThatTriggeredHighPriSuspend !== null) { + componentsThatTriggeredHighPriSuspend.forEach(function(name) { + return componentsThatTriggeredSuspendNames.push(name); + }); + } + + componentsThatTriggeredHighPriSuspend = null; + + var componentNamesString = componentNames.sort().join(", "); + var componentThatTriggeredSuspenseError = ""; + if (componentsThatTriggeredSuspendNames.length > 0) { + componentThatTriggeredSuspenseError = + "The following components triggered a user-blocking update:" + + "\n\n" + + " " + + componentsThatTriggeredSuspendNames.sort().join(", ") + + "\n\n" + + "that was then suspended by:" + + "\n\n" + + " " + + componentNamesString; + } else { + componentThatTriggeredSuspenseError = + "A user-blocking update was suspended by:" + + "\n\n" + + " " + + componentNamesString; + } + + warningWithoutStack$1( + false, + "%s" + + "\n\n" + + "The fix is to split the update into multiple parts: a user-blocking " + + "update to provide immediate feedback, and another update that " + + "triggers the bulk of the changes." + + "\n\n" + + "Refer to the documentation for useSuspenseTransition to learn how " + + "to implement this pattern.", + // TODO: Add link to React docs with more information, once it exists + componentThatTriggeredSuspenseError + ); } + } +} - var prevType = fiber.elementType; - var nextType = element.type; +function computeThreadID(root, expirationTime) { + // Interaction threads are unique per root and expiration time. + return expirationTime * 1000 + root.interactionThreadID; +} - // If we got here, we know types aren't === equal. - var needsCompareFamilies = false; +function markSpawnedWork(expirationTime) { + if (!enableSchedulerTracing) { + return; + } + if (spawnedWorkDuringRender === null) { + spawnedWorkDuringRender = [expirationTime]; + } else { + spawnedWorkDuringRender.push(expirationTime); + } +} - var $$typeofNextType = - typeof nextType === "object" && nextType !== null - ? nextType.$$typeof - : null; +function scheduleInteractions(root, expirationTime, interactions) { + if (!enableSchedulerTracing) { + return; + } - switch (fiber.tag) { - case ClassComponent: { - if (typeof nextType === "function") { - needsCompareFamilies = true; - } - break; - } - case FunctionComponent: { - if (typeof nextType === "function") { - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - // We don't know the inner type yet. - // We're going to assume that the lazy inner type is stable, - // and so it is sufficient to avoid reconciling it away. - // We're not going to unwrap or actually use the new lazy type. - needsCompareFamilies = true; - } - break; - } - case ForwardRef: { - if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - needsCompareFamilies = true; - } - break; - } - case MemoComponent: - case SimpleMemoComponent: { - if ($$typeofNextType === REACT_MEMO_TYPE) { - // TODO: if it was but can no longer be simple, - // we shouldn't set this. - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - needsCompareFamilies = true; + if (interactions.size > 0) { + var pendingInteractionMap = root.pendingInteractionMap; + var pendingInteractions = pendingInteractionMap.get(expirationTime); + if (pendingInteractions != null) { + interactions.forEach(function(interaction) { + if (!pendingInteractions.has(interaction)) { + // Update the pending async work count for previously unscheduled interaction. + interaction.__count++; } - break; - } - default: - return false; + + pendingInteractions.add(interaction); + }); + } else { + pendingInteractionMap.set(expirationTime, new Set(interactions)); + + // Update the pending async work count for the current interactions. + interactions.forEach(function(interaction) { + interaction.__count++; + }); } - // Check if both types have a family and it's the same one. - if (needsCompareFamilies) { - // Note: memo() and forwardRef() we'll compare outer rather than inner type. - // This means both of them need to be registered to preserve state. - // If we unwrapped and compared the inner types for wrappers instead, - // then we would risk falsely saying two separate memo(Foo) - // calls are equivalent because they wrap the same Foo function. - var prevFamily = resolveFamily(prevType); - if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { - return true; - } + var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { + var threadID = computeThreadID(root, expirationTime); + subscriber.onWorkScheduled(interactions, threadID); } - return false; } } -function markFailedErrorBoundaryForHotReloading(fiber) { - { - if (resolveFamily === null) { - // Hot reloading is disabled. - return; - } - if (typeof WeakSet !== "function") { - return; - } - if (failedBoundaries === null) { - failedBoundaries = new WeakSet(); - } - failedBoundaries.add(fiber); +function schedulePendingInteractions(root, expirationTime) { + // This is called when work is scheduled on a root. + // It associates the current interactions with the newly-scheduled expiration. + // They will be restored when that expiration is later committed. + if (!enableSchedulerTracing) { + return; } -} - -var scheduleRefresh = function(root, update) { - { - if (resolveFamily === null) { - // Hot reloading is disabled. - return; - } - var _staleFamilies = update.staleFamilies, - _updatedFamilies = update.updatedFamilies; - flushPassiveEffects(); - flushSync(function() { - scheduleFibersWithFamiliesRecursively( - root.current, - _updatedFamilies, - _staleFamilies - ); - }); - } -}; + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); +} -var scheduleRoot = function(root, element) { - { - if (root.context !== emptyContextObject) { - // Super edge case: root has a legacy _renderSubtree context - // but we don't know the parentComponent so we can't pass it. - // Just ignore. We'll delete this with _renderSubtree code path later. - return; - } - flushPassiveEffects(); - updateContainerAtExpirationTime(element, root, null, Sync, null); +function startWorkOnPendingInteractions(root, expirationTime) { + // This is called when new work is started on a root. + if (!enableSchedulerTracing) { + return; } -}; - -function scheduleFibersWithFamiliesRecursively( - fiber, - updatedFamilies, - staleFamilies -) { - { - var alternate = fiber.alternate, - child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type; - var candidateType = null; - switch (tag) { - case FunctionComponent: - case SimpleMemoComponent: - case ClassComponent: - candidateType = type; - break; - case ForwardRef: - candidateType = type.render; - break; - default: - break; + // Determine which interactions this batch of work currently includes, So that + // we can accurately attribute time spent working on it, And so that cascading + // work triggered during the render phase will be associated with it. + var interactions = new Set(); + root.pendingInteractionMap.forEach(function( + scheduledInteractions, + scheduledExpirationTime + ) { + if (scheduledExpirationTime >= expirationTime) { + scheduledInteractions.forEach(function(interaction) { + return interactions.add(interaction); + }); } + }); - if (resolveFamily === null) { - throw new Error("Expected resolveFamily to be set during hot reload."); - } + // Store the current set of interactions on the FiberRoot for a few reasons: + // We can re-use it in hot functions like renderRoot() without having to + // recalculate it. We will also use it in commitWork() to pass to any Profiler + // onRender() hooks. This also provides DevTools with a way to access it when + // the onCommitRoot() hook is called. + root.memoizedInteractions = interactions; - var needsRender = false; - var needsRemount = false; - if (candidateType !== null) { - var family = resolveFamily(candidateType); - if (family !== undefined) { - if (staleFamilies.has(family)) { - needsRemount = true; - } else if (updatedFamilies.has(family)) { - needsRender = true; - } - } - } - if (failedBoundaries !== null) { - if ( - failedBoundaries.has(fiber) || - (alternate !== null && failedBoundaries.has(alternate)) - ) { - needsRemount = true; + if (interactions.size > 0) { + var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { + var threadID = computeThreadID(root, expirationTime); + try { + subscriber.onWorkStarted(interactions, threadID); + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); } } - - if (needsRemount) { - fiber._debugNeedsRemount = true; - } - if (needsRemount || needsRender) { - scheduleWork(fiber, Sync); - } - if (child !== null && !needsRemount) { - scheduleFibersWithFamiliesRecursively( - child, - updatedFamilies, - staleFamilies - ); - } - if (sibling !== null) { - scheduleFibersWithFamiliesRecursively( - sibling, - updatedFamilies, - staleFamilies - ); - } } } -var findHostInstancesForRefresh = function(root, families) { - { - var hostInstances = new Set(); - var types = new Set( - families.map(function(family) { - return family.current; - }) - ); - findHostInstancesForMatchingFibersRecursively( - root.current, - types, - hostInstances - ); - return hostInstances; +function finishPendingInteractions(root, committedExpirationTime) { + if (!enableSchedulerTracing) { + return; } -}; -function findHostInstancesForMatchingFibersRecursively( - fiber, - types, - hostInstances -) { - { - var child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type; + var earliestRemainingTimeAfterCommit = root.firstPendingTime; - var candidateType = null; - switch (tag) { - case FunctionComponent: - case SimpleMemoComponent: - case ClassComponent: - candidateType = type; - break; - case ForwardRef: - candidateType = type.render; - break; - default: - break; - } + var subscriber = void 0; - var didMatch = false; - if (candidateType !== null) { - if (types.has(candidateType)) { - didMatch = true; - } + try { + subscriber = tracing.__subscriberRef.current; + if (subscriber !== null && root.memoizedInteractions.size > 0) { + var threadID = computeThreadID(root, committedExpirationTime); + subscriber.onWorkStopped(root.memoizedInteractions, threadID); } + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } finally { + // Clear completed interactions from the pending Map. + // Unless the render was suspended or cascading work was scheduled, + // In which case– leave pending interactions until the subsequent render. + var pendingInteractionMap = root.pendingInteractionMap; + pendingInteractionMap.forEach(function( + scheduledInteractions, + scheduledExpirationTime + ) { + // Only decrement the pending interaction count if we're done. + // If there's still work at the current priority, + // That indicates that we are waiting for suspense data. + if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { + pendingInteractionMap.delete(scheduledExpirationTime); - if (didMatch) { - // We have a match. This only drills down to the closest host components. - // There's no need to search deeper because for the purpose of giving - // visual feedback, "flashing" outermost parent rectangles is sufficient. - findHostInstancesForFiberShallowly(fiber, hostInstances); - } else { - // If there's no match, maybe there will be one further down in the child tree. - if (child !== null) { - findHostInstancesForMatchingFibersRecursively( - child, - types, - hostInstances - ); + scheduledInteractions.forEach(function(interaction) { + interaction.__count--; + + if (subscriber !== null && interaction.__count === 0) { + try { + subscriber.onInteractionScheduledWorkCompleted(interaction); + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } + } + }); } - } - - if (sibling !== null) { - findHostInstancesForMatchingFibersRecursively( - sibling, - types, - hostInstances - ); - } + }); } } -function findHostInstancesForFiberShallowly(fiber, hostInstances) { - { - var foundHostInstances = findChildHostInstancesForFiberShallowly( - fiber, - hostInstances - ); - if (foundHostInstances) { - return; +var onCommitFiberRoot = null; +var onCommitFiberUnmount = 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; + } + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + 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) { + { + warningWithoutStack$1( + false, + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://fb.me/react-devtools" + ); } - // If we didn't find any host children, fallback to closest host parent. - var node = fiber; - while (true) { - switch (node.tag) { - case HostComponent: - hostInstances.add(node.stateNode); - return; - case HostPortal: - hostInstances.add(node.stateNode.containerInfo); - return; - case HostRoot: - hostInstances.add(node.stateNode.containerInfo); - return; + // DevTools exists, even though it doesn't support Fiber. + return true; + } + try { + var rendererID = hook.inject(internals); + // We have successfully injected, so now it is safe to set up hooks. + onCommitFiberRoot = function(root, expirationTime) { + try { + var didError = (root.current.effectTag & DidCapture) === DidCapture; + if (enableProfilerTimer) { + var currentTime = requestCurrentTime(); + var priorityLevel = inferPriorityFromExpirationTime( + currentTime, + expirationTime + ); + hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); + } else { + hook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); + } } - if (node.return === null) { - throw new Error("Expected to reach root first."); + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); + } } - node = node.return; + }; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s.", + err + ); } } + // DevTools exists + return true; } -function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { - { - var node = fiber; - var foundHostInstances = false; - while (true) { - if (node.tag === HostComponent) { - // We got a match. - foundHostInstances = true; - hostInstances.add(node.stateNode); - // There may still be more, so keep searching. - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - if (node === fiber) { - return foundHostInstances; - } - while (node.sibling === null) { - if (node.return === null || node.return === fiber) { - return foundHostInstances; - } - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } +function onCommitRoot(root, expirationTime) { + if (typeof onCommitFiberRoot === "function") { + onCommitFiberRoot(root, expirationTime); + } +} + +function onCommitUnmount(fiber) { + if (typeof onCommitFiberUnmount === "function") { + onCommitFiberUnmount(fiber); } - return false; } var hasBadMapPolyfill = void 0; @@ -18876,7 +20913,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.memoizedProps = null; this.updateQueue = null; this.memoizedState = null; - this.contextDependencies = null; + this.dependencies = null; this.mode = mode; @@ -19036,7 +21073,19 @@ function createWorkInProgress(current, pendingProps, expirationTime) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + + // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + expirationTime: currentDependencies.expirationTime, + firstContext: currentDependencies.firstContext, + listeners: currentDependencies.listeners, + responders: currentDependencies.responders + }; // These will be overridden during the parent's reconciliation workInProgress.sibling = current.sibling; @@ -19070,8 +21119,87 @@ function createWorkInProgress(current, pendingProps, expirationTime) { return workInProgress; } -function createHostRootFiber(isConcurrent) { - var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext; +// Used to reuse a Fiber for a second pass. +function resetWorkInProgress(workInProgress, renderExpirationTime) { + // This resets the Fiber to what createFiber or createWorkInProgress would + // have set the values to before during the first pass. Ideally this wouldn't + // be necessary but unfortunately many code paths reads from the workInProgress + // 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 + // that child fiber is setting, not the reconciliation. + workInProgress.effectTag &= Placement; + + // The effect list is no longer valid. + workInProgress.nextEffect = null; + workInProgress.firstEffect = null; + workInProgress.lastEffect = null; + + var current = workInProgress.alternate; + if (current === null) { + // Reset to createFiber's initial values. + workInProgress.childExpirationTime = NoWork; + workInProgress.expirationTime = renderExpirationTime; + + workInProgress.child = null; + workInProgress.memoizedProps = null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + + workInProgress.dependencies = null; + + if (enableProfilerTimer) { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = 0; + workInProgress.treeBaseDuration = 0; + } + } else { + // Reset to the cloned values that createWorkInProgress would've. + workInProgress.childExpirationTime = current.childExpirationTime; + workInProgress.expirationTime = current.expirationTime; + + workInProgress.child = current.child; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; + + // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + expirationTime: currentDependencies.expirationTime, + firstContext: currentDependencies.firstContext, + listeners: currentDependencies.listeners, + responders: currentDependencies.responders + }; + + if (enableProfilerTimer) { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; + } + } + + return workInProgress; +} + +function createHostRootFiber(tag) { + var mode = void 0; + if (tag === ConcurrentRoot) { + mode = ConcurrentMode | BatchedMode | StrictMode; + } else if (tag === BatchedRoot) { + mode = BatchedMode | StrictMode; + } else { + mode = NoMode; + } if (enableProfilerTimer && isDevToolsPresent) { // Always collect profile timings when DevTools are present. @@ -19119,23 +21247,24 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode( - pendingProps, - mode | ConcurrentMode | StrictMode, - expirationTime, - key - ); + fiberTag = Mode; + mode |= ConcurrentMode | BatchedMode | StrictMode; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode( - pendingProps, - mode | StrictMode, - expirationTime, - key - ); + fiberTag = Mode; + mode |= StrictMode; + break; case REACT_PROFILER_TYPE: return createFiberFromProfiler(pendingProps, mode, expirationTime, key); case REACT_SUSPENSE_TYPE: return createFiberFromSuspense(pendingProps, mode, expirationTime, key); + case REACT_SUSPENSE_LIST_TYPE: + return createFiberFromSuspenseList( + pendingProps, + mode, + expirationTime, + key + ); default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -19159,20 +21288,9 @@ function createFiberFromTypeAndProps( fiberTag = LazyComponent; resolvedType = null; break getTag; - case REACT_EVENT_COMPONENT_TYPE: - if (enableEventAPI) { - return createFiberFromEventComponent( - type, - pendingProps, - mode, - expirationTime, - key - ); - } - break; - case REACT_EVENT_TARGET_TYPE: - if (enableEventAPI) { - return createFiberFromEventTarget( + case REACT_FUNDAMENTAL_TYPE: + if (enableFundamentalAPI) { + return createFiberFromFundamental( type, pendingProps, mode, @@ -19204,10 +21322,12 @@ function createFiberFromTypeAndProps( (function() { { throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (type == null ? type : typeof type) + - "." + - info + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (type == null ? type : typeof type) + + "." + + info + ) ); } })(); @@ -19252,35 +21372,17 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { return fiber; } -function createFiberFromEventComponent( - eventComponent, - pendingProps, - mode, - expirationTime, - key -) { - var fiber = createFiber(EventComponent, pendingProps, key, mode); - fiber.elementType = eventComponent; - fiber.type = eventComponent; - fiber.expirationTime = expirationTime; - return fiber; -} - -function createFiberFromEventTarget( - eventTarget, +function createFiberFromFundamental( + fundamentalComponent, pendingProps, mode, expirationTime, key ) { - var fiber = createFiber(EventTarget, pendingProps, key, mode); - fiber.elementType = eventTarget; - fiber.type = eventTarget; + var fiber = createFiber(FundamentalComponent, pendingProps, key, mode); + fiber.elementType = fundamentalComponent; + fiber.type = fundamentalComponent; fiber.expirationTime = expirationTime; - // Store latest props - fiber.stateNode = { - props: pendingProps - }; return fiber; } @@ -19306,29 +21408,28 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { return fiber; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - var fiber = createFiber(Mode, pendingProps, key, mode); +function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { + var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); - // TODO: The Mode fiber shouldn't have a type. It has a tag. - var type = - (mode & ConcurrentMode) === NoContext - ? REACT_STRICT_MODE_TYPE - : REACT_CONCURRENT_MODE_TYPE; - fiber.elementType = type; - fiber.type = type; + // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + fiber.type = REACT_SUSPENSE_TYPE; + fiber.elementType = REACT_SUSPENSE_TYPE; fiber.expirationTime = expirationTime; return fiber; } -function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { - var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); - - // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. - var type = REACT_SUSPENSE_TYPE; - fiber.elementType = type; - fiber.type = type; - +function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) { + var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode); + { + // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + fiber.type = REACT_SUSPENSE_LIST_TYPE; + } + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; fiber.expirationTime = expirationTime; return fiber; } @@ -19340,7 +21441,7 @@ function createFiberFromText(content, mode, expirationTime) { } function createFiberFromHostInstanceForDeletion() { - var fiber = createFiber(HostComponent, null, null, NoContext); + var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. fiber.elementType = "DELETED"; fiber.type = "DELETED"; @@ -19364,7 +21465,7 @@ function assignFiberPropertiesInDEV(target, source) { if (target === null) { // This Fiber's initial properties will always be overwritten. // We only use a Fiber to ensure the same hidden class so DEV isn't slow. - target = createFiber(IndeterminateComponent, null, null, NoContext); + target = createFiber(IndeterminateComponent, null, null, NoMode); } // This is intentionally written as a list of all properties. @@ -19387,7 +21488,7 @@ function assignFiberPropertiesInDEV(target, source) { target.memoizedProps = source.memoizedProps; target.updateQueue = source.updateQueue; target.memoizedState = source.memoizedState; - target.contextDependencies = source.contextDependencies; + target.dependencies = source.dependencies; target.mode = source.mode; target.effectTag = source.effectTag; target.nextEffect = source.nextEffect; @@ -19424,12 +21525,13 @@ function assignFiberPropertiesInDEV(target, source) { // The types are defined separately within this file to ensure they stay in sync. // (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.) -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pendingChildren = null; this.pingCache = null; - this.pendingCommitExpirationTime = NoWork; + this.finishedExpirationTime = NoWork; this.finishedWork = null; this.timeoutHandle = noTimeout; this.context = null; @@ -19449,12 +21551,12 @@ function FiberRootNode(containerInfo, hydrate) { } } -function createFiberRoot(containerInfo, isConcurrent, hydrate) { - var root = new FiberRootNode(containerInfo, hydrate); +function createFiberRoot(containerInfo, tag, hydrate) { + var root = new FiberRootNode(containerInfo, tag, hydrate); // Cyclic construction. This cheats the type system right now because // stateNode is any. - var uninitializedFiber = createHostRootFiber(isConcurrent); + var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -19500,7 +21602,13 @@ function getContextForSubtree(parentComponent) { return parentContext; } -function scheduleRootUpdate(current$$1, element, expirationTime, callback) { +function scheduleRootUpdate( + current$$1, + element, + expirationTime, + suspenseConfig, + callback +) { { if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; @@ -19515,7 +21623,7 @@ function scheduleRootUpdate(current$$1, element, expirationTime, callback) { } } - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property // being called "element". update.payload = { element: element }; @@ -19533,7 +21641,9 @@ function scheduleRootUpdate(current$$1, element, expirationTime, callback) { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(current$$1, update); scheduleWork(current$$1, expirationTime); @@ -19545,6 +21655,7 @@ function updateContainerAtExpirationTime( container, parentComponent, expirationTime, + suspenseConfig, callback ) { // TODO: If this is a nested container, this won't be the root. @@ -19569,7 +21680,13 @@ function updateContainerAtExpirationTime( container.pendingContext = context; } - return scheduleRootUpdate(current$$1, element, expirationTime, callback); + return scheduleRootUpdate( + current$$1, + element, + expirationTime, + suspenseConfig, + callback + ); } function findHostInstance(component) { @@ -19578,15 +21695,19 @@ function findHostInstance(component) { if (typeof component.render === "function") { (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } else { (function() { { throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } })(); @@ -19606,15 +21727,19 @@ function findHostInstanceWithWarning(component, methodName) { if (typeof component.render === "function") { (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } else { (function() { { throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } })(); @@ -19664,19 +21789,31 @@ function findHostInstanceWithWarning(component, methodName) { return findHostInstance(component); } -function createContainer(containerInfo, isConcurrent, hydrate) { - return createFiberRoot(containerInfo, isConcurrent, hydrate); +function createContainer(containerInfo, tag, hydrate) { + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current; var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, current$$1); + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(current$$1); + } + } + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); return updateContainerAtExpirationTime( element, container, parentComponent, expirationTime, + suspenseConfig, callback ); } @@ -19733,7 +21870,9 @@ var setSuspenseHandler = null; id--; } if (currentHook !== null) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } var newState = copyWithSet(currentHook.memoizedState, path, value); currentHook.memoizedState = newState; @@ -19752,7 +21891,9 @@ var setSuspenseHandler = null; // Support DevTools props for function components, forwardRef, memo, host components, etc. overrideProps = function(fiber, path, value) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); if (fiber.alternate) { fiber.alternate.pendingProps = fiber.pendingProps; @@ -19761,7 +21902,9 @@ var setSuspenseHandler = null; }; scheduleUpdate = function(fiber) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } scheduleWork(fiber, Sync); }; @@ -19800,7 +21943,11 @@ function injectIntoDevTools(devToolsConfig) { findHostInstancesForRefresh: findHostInstancesForRefresh, scheduleRefresh: scheduleRefresh, scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: function() { + return current; + } }) ); } @@ -20117,7 +22264,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps ) ) { - throw ReactError("Do not override existing functions."); + throw ReactError(Error("Do not override existing functions.")); } })(); // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, @@ -20475,9 +22622,9 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { }; // Module provided by RN: -var emptyObject$1 = {}; +var emptyObject$2 = {}; { - Object.freeze(emptyObject$1); + Object.freeze(emptyObject$2); } var getInspectorDataForViewTag = void 0; @@ -20510,9 +22657,9 @@ var getInspectorDataForViewTag = void 0; var getHostProps = function(fiber) { var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$1; + return host.memoizedProps || emptyObject$2; } - return emptyObject$1; + return emptyObject$2; }; var getHostNode = function(fiber, findNodeHandle) { @@ -20558,7 +22705,7 @@ var getInspectorDataForViewTag = void 0; if (!closestInstance) { return { hierarchy: [], - props: emptyObject$1, + props: emptyObject$2, selection: null, source: null }; @@ -20667,8 +22814,9 @@ function findNodeHandle(componentOrHandle) { setBatchingImplementation( batchedUpdates$1, - interactiveUpdates$1, - flushInteractiveUpdates$1 + discreteUpdates$1, + flushDiscreteUpdates, + batchedEventUpdates$1 ); function computeComponentStackForErrorReporting(reactTag) { @@ -20686,6 +22834,25 @@ var ReactNativeRenderer = { findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + if (handle._nativeTag == null) { + !(handle._nativeTag != null) + ? warningWithoutStack$1( + false, + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ) + : void 0; + return; + } + + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + }, + setNativeProps: setNativeProps, render: function(element, containerTag, callback) { @@ -20694,7 +22861,7 @@ var ReactNativeRenderer = { 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, false, false); + root = createContainer(containerTag, LegacyRoot, false); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index 2f5b01eb2e6c14..932146e9d9a381 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -23,12 +23,11 @@ var checkPropTypes = require("prop-types/checkPropTypes"); var Scheduler = require("scheduler"); var tracing = require("scheduler/tracing"); -// Do not require this module directly! Use a normal error constructor with +// Do not require this module directly! Use normal `invariant` calls with // template literal strings. The messages will be converted to ReactError during // build, and in production they will be minified. -function ReactError(message) { - var error = new Error(message); +function ReactError(error) { error.name = "Invariant Violation"; return error; } @@ -70,9 +69,11 @@ function recomputePluginOrdering() { (function() { if (!(pluginIndex > -1)) { throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); } })(); @@ -82,9 +83,11 @@ function recomputePluginOrdering() { (function() { if (!pluginModule.extractEvents) { throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); } })(); @@ -100,11 +103,13 @@ function recomputePluginOrdering() { ) ) { throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } })(); @@ -124,9 +129,11 @@ function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { (function() { if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ) ); } })(); @@ -167,9 +174,11 @@ function publishRegistrationName(registrationName, pluginModule, eventName) { (function() { if (!!registrationNameModules[registrationName]) { throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); } })(); @@ -230,7 +239,9 @@ function injectEventPluginOrder(injectedEventPluginOrder) { (function() { if (!!eventPluginOrder) { throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); } })(); @@ -263,9 +274,11 @@ function injectEventPluginsByName(injectedNamesToPlugins) { (function() { if (!!namesToPlugins[pluginName]) { throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); } })(); @@ -345,7 +358,9 @@ var invokeGuardedCallbackImpl = function( (function() { if (!(typeof document !== "undefined")) { throw ReactError( - "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." + Error( + "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." + ) ); } })(); @@ -574,7 +589,9 @@ function clearCaughtError() { (function() { { throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -788,7 +805,7 @@ function executeDirectDispatch(event) { var dispatchInstance = event._dispatchInstances; (function() { if (!!Array.isArray(dispatchListener)) { - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); } })(); event.currentTarget = dispatchListener @@ -826,7 +843,9 @@ function accumulateInto(current, next) { (function() { if (!(next != null)) { throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); } })(); @@ -914,7 +933,9 @@ function runEventsInBatch(events) { (function() { if (!!eventQueue) { throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); } })(); @@ -1015,11 +1036,13 @@ function getListener(inst, registrationName) { (function() { if (!(!listener || typeof listener === "function")) { throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); } })(); @@ -1092,8 +1115,8 @@ var SimpleMemoComponent = 15; var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedSuspenseComponent = 18; -var EventComponent = 19; -var EventTarget = 20; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; function getParent(inst) { do { @@ -1615,7 +1638,9 @@ function releasePooledEvent(event) { (function() { if (!(event instanceof EventConstructor)) { throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); } })(); @@ -1727,7 +1752,7 @@ function getTouchIdentifier(_ref) { (function() { if (!(identifier != null)) { - throw ReactError("Touch object is missing identifier."); + throw ReactError(Error("Touch object is missing identifier.")); } })(); { @@ -1767,7 +1792,7 @@ function recordTouchMove(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.error( + console.warn( "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -1788,7 +1813,7 @@ function recordTouchEnd(touch) { touchRecord.currentTimeStamp = timestampForTouch(touch); touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } else { - console.error( + console.warn( "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -1860,7 +1885,9 @@ function accumulate(current, next) { (function() { if (!(next != null)) { throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error( + "accumulate(...): Accumulated items must not be null or undefined." + ) ); } })(); @@ -2484,7 +2511,9 @@ var ReactNativeBridgeEventPlugin = { (function() { if (!(bubbleDispatchConfig || directDispatchConfig)) { throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); } })(); @@ -2531,20 +2560,20 @@ injection.injectEventPluginsByName({ ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin }); -var instanceCache = {}; -var instanceProps = {}; +var instanceCache = new Map(); +var instanceProps = new Map(); function precacheFiberNode(hostInst, tag) { - instanceCache[tag] = hostInst; + instanceCache.set(tag, hostInst); } function uncacheFiberNode(tag) { - delete instanceCache[tag]; - delete instanceProps[tag]; + instanceCache.delete(tag); + instanceProps.delete(tag); } function getInstanceFromTag(tag) { - return instanceCache[tag] || null; + return instanceCache.get(tag) || null; } function getTagFromInstance(inst) { @@ -2554,18 +2583,18 @@ function getTagFromInstance(inst) { } (function() { if (!tag) { - throw ReactError("All native instances should have a tag."); + throw ReactError(Error("All native instances should have a tag.")); } })(); return tag; } function getFiberCurrentPropsFromNode$1(stateNode) { - return instanceProps[stateNode._nativeTag] || null; + return instanceProps.get(stateNode._nativeTag) || null; } function updateFiberProps(tag, props) { - instanceProps[tag] = props; + instanceProps.set(tag, props); } // Use to restore controlled state after a change event has fired. @@ -2585,7 +2614,9 @@ function restoreStateOfTarget(target) { (function() { if (!(typeof restoreImpl === "function")) { throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -2614,6 +2645,26 @@ function restoreStateIfNeeded() { } } +var debugRenderPhaseSideEffects = false; +var debugRenderPhaseSideEffectsForStrictMode = false; +var enableUserTimingAPI = true; +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; +var warnAboutDeprecatedLifecycles = true; +var enableProfilerTimer = true; +var enableSchedulerTracing = true; +var enableSuspenseServerRenderer = false; + +var warnAboutDeprecatedSetNativeProps = false; +var enableFlareAPI = false; +var enableFundamentalAPI = false; + +var revertPassiveEffectsChange = false; + +var enableSuspenseCallback = false; +var warnAboutDefaultPropsOnFunctionComponents = false; + +// Only used in www builds. + // Used as a way to call batchedUpdates when we don't have a reference to // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when @@ -2621,45 +2672,50 @@ function restoreStateIfNeeded() { // scheduled work and instead do synchronous work. // Defaults -var _batchedUpdatesImpl = function(fn, bookkeeping) { +var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; -var _flushInteractiveUpdatesImpl = function() {}; +var flushDiscreteUpdatesImpl = function() {}; +var isInsideEventHandler = false; + +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} -var isBatching = false; function batchedUpdates(fn, bookkeeping) { - if (isBatching) { + if (isInsideEventHandler) { // If we are currently inside another batch, we need to wait until it // fully completes before restoring state. return fn(bookkeeping); } - isBatching = true; + isInsideEventHandler = true; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - // Here we wait until all updates have propagated, which is important - // when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - // Then we restore state of any controlled component. - isBatching = false; - var controlledComponentsHavePendingUpdates = needsStateRestore(); - if (controlledComponentsHavePendingUpdates) { - // If a controlled event was fired, we may need to restore the state of - // the DOM node back to the controlled value. This is necessary when React - // bails out of the update without touching the DOM. - _flushInteractiveUpdatesImpl(); - restoreStateIfNeeded(); - } + isInsideEventHandler = false; + finishEventHandler(); } } function setBatchingImplementation( - batchedUpdatesImpl, - interactiveUpdatesImpl, - flushInteractiveUpdatesImpl + _batchedUpdatesImpl, + _discreteUpdatesImpl, + _flushDiscreteUpdatesImpl, + _batchedEventUpdatesImpl ) { - _batchedUpdatesImpl = batchedUpdatesImpl; - _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; + batchedUpdatesImpl = _batchedUpdatesImpl; + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; } /** @@ -2879,6 +2935,11 @@ if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { current: null }; } +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. @@ -2893,6 +2954,8 @@ var REACT_STRICT_MODE_TYPE = hasSymbol var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; +// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") @@ -2901,19 +2964,15 @@ var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 0xead0; var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -var REACT_EVENT_COMPONENT_TYPE = hasSymbol - ? Symbol.for("react.event_component") +var REACT_FUNDAMENTAL_TYPE = hasSymbol + ? Symbol.for("react.fundamental") : 0xead5; -var REACT_EVENT_TARGET_TYPE = hasSymbol - ? Symbol.for("react.event_target") - : 0xead6; - -// React event targets -var REACT_EVENT_TARGET_TOUCH_HIT = hasSymbol - ? Symbol.for("react.event_target.touch_hit") - : 0xead7; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; @@ -2939,22 +2998,6 @@ function refineResolvedLazyComponent(lazyComponent) { return lazyComponent._status === Resolved ? lazyComponent._result : null; } -var debugRenderPhaseSideEffects = false; -var debugRenderPhaseSideEffectsForStrictMode = false; -var enableUserTimingAPI = true; -var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; -var warnAboutDeprecatedLifecycles = true; -var enableProfilerTimer = true; -var enableSchedulerTracing = true; -var enableSuspenseServerRenderer = false; - -var disableYielding = false; - -var warnAboutDeprecatedSetNativeProps = false; -var enableEventAPI = false; - -// Only used in www builds. - function getWrappedName(outerType, innerType, wrapperName) { var functionName = innerType.displayName || innerType.name || ""; return ( @@ -2984,8 +3027,6 @@ function getComponentName(type) { return type; } switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -2996,6 +3037,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if (typeof type === "object") { switch (type.$$typeof) { @@ -3015,28 +3058,6 @@ function getComponentName(type) { } break; } - case REACT_EVENT_COMPONENT_TYPE: { - if (enableEventAPI) { - var eventComponent = type; - var displayName = eventComponent.displayName; - if (displayName !== undefined) { - return displayName; - } - } - break; - } - case REACT_EVENT_TARGET_TYPE: { - if (enableEventAPI) { - var eventTarget = type; - if (eventTarget.type === REACT_EVENT_TARGET_TOUCH_HIT) { - return "TouchHitTarget"; - } - var _displayName = eventTarget.displayName; - if (_displayName !== undefined) { - return _displayName; - } - } - } } } return null; @@ -3137,7 +3158,7 @@ function isMounted(component) { function assertIsMounted(fiber) { (function() { if (!(isFiberMountedImpl(fiber) === MOUNTED)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } })(); } @@ -3149,7 +3170,9 @@ function findCurrentFiberUsingSlowPath(fiber) { var state = isFiberMountedImpl(fiber); (function() { if (!(state !== UNMOUNTED)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); if (state === MOUNTING) { @@ -3205,7 +3228,9 @@ function findCurrentFiberUsingSlowPath(fiber) { // way this could possibly happen is if this was unmounted, if at all. (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } @@ -3261,7 +3286,9 @@ function findCurrentFiberUsingSlowPath(fiber) { (function() { if (!didFindChild) { throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } })(); @@ -3271,7 +3298,9 @@ function findCurrentFiberUsingSlowPath(fiber) { (function() { if (!(a.alternate === b)) { throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -3280,7 +3309,7 @@ function findCurrentFiberUsingSlowPath(fiber) { // unmounted. (function() { if (!(a.tag === HostRoot)) { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } })(); if (a.stateNode.current === a) { @@ -3953,7 +3982,9 @@ function shim() { (function() { { throw ReactError( - "The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -3962,6 +3993,7 @@ function shim() { // Persistence (when unsupported) var supportsPersistence = false; var cloneInstance = shim; +var cloneFundamentalInstance = shim; var createContainerChildSet = shim; var appendChildToContainerChildSet = shim; var finalizeContainerChildren = shim; @@ -3976,7 +4008,9 @@ function shim$1() { (function() { { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -4095,7 +4129,7 @@ function createTextInstance( (function() { if (!hostContext.isInAParentText) { throw ReactError( - "Text strings must be rendered within a component." + Error("Text strings must be rendered within a component.") ); } })(); @@ -4162,16 +4196,6 @@ function getChildHostContext(parentHostContext, type, rootContainerInstance) { } } -function getChildHostContextForEventComponent(parentHostContext) { - // TODO: add getChildHostContextForEventComponent implementation - return parentHostContext; -} - -function getChildHostContextForEventTarget(parentHostContext, type) { - // TODO: add getChildHostContextForEventTarget implementation - return parentHostContext; -} - function getPublicInstance(instance) { return instance; } @@ -4196,6 +4220,7 @@ function resetAfterCommit(containerInfo) { } var isPrimaryRenderer = true; +var warnsIfNotActing = true; var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; @@ -4336,7 +4361,9 @@ function insertInContainerBefore(parentInstance, child, beforeChild) { // For more info on pros/cons see PR #8560 description. (function() { if (!(typeof parentInstance !== "number")) { - throw ReactError("Container does not support insertBefore operation"); + throw ReactError( + Error("Container does not support insertBefore operation") + ); } })(); } @@ -4409,32 +4436,38 @@ function unhideTextInstance(textInstance, text) { throw new Error("Not yet implemented."); } -function mountEventComponent(eventComponentInstance) { +function mountResponderInstance( + responder, + responderInstance, + props, + state, + instance, + rootContainerInstance +) { throw new Error("Not yet implemented."); } -function updateEventComponent(eventComponentInstance) { +function unmountResponderInstance(responderInstance) { throw new Error("Not yet implemented."); } -function unmountEventComponent(eventComponentInstance) { +function getFundamentalComponentInstance(fundamentalInstance) { throw new Error("Not yet implemented."); } -function getEventTargetChildElement(type, props) { +function mountFundamentalComponent(fundamentalInstance) { throw new Error("Not yet implemented."); } -function handleEventTarget( - type, - props, - rootContainerInstance, - internalInstanceHandle -) { +function shouldUpdateFundamentalComponent(fundamentalInstance) { throw new Error("Not yet implemented."); } -function commitEventTarget(type, props, instance, parentInstance) { +function updateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} + +function unmountFundamentalComponent(fundamentalInstance) { throw new Error("Not yet implemented."); } @@ -5168,7 +5201,9 @@ function pushTopLevelContextObject(fiber, context, didChange) { (function() { if (!(contextStackCursor.current === emptyContextObject)) { throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -5216,10 +5251,12 @@ function processChildContext(fiber, type, parentContext) { (function() { if (!(contextKey in childContextTypes)) { throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); } })(); @@ -5270,7 +5307,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { (function() { if (!instance) { throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -5305,7 +5344,9 @@ function findCurrentUnmaskedContext(fiber) { (function() { if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -5328,94 +5369,17 @@ function findCurrentUnmaskedContext(fiber) { (function() { { throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); } -var onCommitFiberRoot = null; -var onCommitFiberUnmount = null; -var hasLoggedError = false; - -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); - } - } - }; -} - -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; - -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; - } - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - 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) { - { - warningWithoutStack$1( - false, - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://fb.me/react-devtools" - ); - } - // DevTools exists, even though it doesn't support Fiber. - return true; - } - try { - var rendererID = hook.inject(internals); - // We have successfully injected, so now it is safe to set up hooks. - onCommitFiberRoot = catchErrors(function(root) { - var didError = (root.current.effectTag & DidCapture) === DidCapture; - hook.onCommitFiberRoot(rendererID, root, undefined, didError); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); - } - } - // DevTools exists - return true; -} - -function onCommitRoot(root) { - if (typeof onCommitFiberRoot === "function") { - onCommitFiberRoot(root); - } -} - -function onCommitUnmount(fiber) { - if (typeof onCommitFiberUnmount === "function") { - onCommitFiberUnmount(fiber); - } -} +var LegacyRoot = 0; +var BatchedRoot = 1; +var ConcurrentRoot = 2; /** * Similar to invariant but only logs a warning if the condition is not met. @@ -5460,6 +5424,7 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority; var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback; var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback; var Scheduler_shouldYield = Scheduler.unstable_shouldYield; +var Scheduler_requestPaint = Scheduler.unstable_requestPaint; var Scheduler_now = Scheduler.unstable_now; var Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel; @@ -5481,7 +5446,9 @@ if (enableSchedulerTracing) { ) ) { throw ReactError( - "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 http://fb.me/react-profiling" + 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 http://fb.me/react-profiling" + ) ); } })(); @@ -5499,15 +5466,14 @@ var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. -var shouldYield = disableYielding - ? function() { - return false; - } // Never yield when `disableYielding` is on - : Scheduler_shouldYield; +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 immediateQueue = null; +var syncQueue = null; var immediateQueueCallbackNode = null; -var isFlushingImmediate = false; +var isFlushingSyncQueue = false; var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. @@ -5539,7 +5505,7 @@ function getCurrentPriorityLevel() { default: (function() { { - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } })(); } @@ -5560,7 +5526,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { default: (function() { { - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } })(); } @@ -5572,76 +5538,82 @@ function runWithPriority(reactPriorityLevel, fn) { } function scheduleCallback(reactPriorityLevel, callback, options) { - if (reactPriorityLevel === ImmediatePriority) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushImmediateQueue`. - if (immediateQueue === null) { - immediateQueue = [callback]; - // Flush the queue in the next tick, at the earliest. - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ); - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - immediateQueue.push(callback); - } - return fakeCallbackNode; - } - // Otherwise pass through to Scheduler. 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 flushImmediateQueue() { +function flushSyncCallbackQueue() { if (immediateQueueCallbackNode !== null) { Scheduler_cancelCallback(immediateQueueCallbackNode); } - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && immediateQueue !== null) { +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. - isFlushingImmediate = true; + isFlushingSyncQueue = true; var i = 0; try { var _isSync = true; - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do { - callback = callback(_isSync); - } while (callback !== null); - } - immediateQueue = null; + var queue = syncQueue; + runWithPriority(ImmediatePriority, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do { + callback = callback(_isSync); + } while (callback !== null); + } + }); + syncQueue = null; } catch (error) { // If something throws, leave the remaining callbacks on the queue. - if (immediateQueue !== null) { - immediateQueue = immediateQueue.slice(i + 1); + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); } // Resume flushing in the next tick Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ); throw error; } finally { - isFlushingImmediate = false; + isFlushingSyncQueue = false; } } } -var NoContext = 0; -var ConcurrentMode = 1; -var StrictMode = 2; -var ProfileMode = 4; +var NoMode = 0; +var StrictMode = 1; +// TODO: Remove BatchedMode and ConcurrentMode by reading from the root +// tag instead +var BatchedMode = 2; +var ConcurrentMode = 4; +var ProfileMode = 8; // Max 31 bit integer. The max integer size in V8 for 32-bit systems. // Math.pow(2, 30) - 1 @@ -5651,9 +5623,10 @@ var MAX_SIGNED_31_BIT_INT = 1073741823; var NoWork = 0; var Never = 1; var Sync = MAX_SIGNED_31_BIT_INT; +var Batched = Sync - 1; var UNIT_SIZE = 10; -var MAGIC_NUMBER_OFFSET = MAX_SIGNED_31_BIT_INT - 1; +var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms. function msToExpirationTime(ms) { @@ -5692,10 +5665,13 @@ function computeAsyncExpiration(currentTime) { ); } -// Same as computeAsyncExpiration but without the bucketing logic. This is -// used to compute timestamps instead of actual expiration times. -function computeAsyncExpirationNoBucket(currentTime) { - return currentTime - LOW_PRIORITY_EXPIRATION / UNIT_SIZE; +function computeSuspenseExpiration(currentTime, timeoutMs) { + // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time? + return computeExpirationBucket( + currentTime, + timeoutMs, + LOW_PRIORITY_BATCH_SIZE + ); } // We intentionally set a higher expiration time for interactive updates in @@ -5867,95 +5843,14 @@ var lowPriorityWarning = function() {}; var lowPriorityWarning$1 = lowPriorityWarning; var ReactStrictModeWarnings = { - discardPendingWarnings: function() {}, - flushPendingDeprecationWarnings: function() {}, - flushPendingUnsafeLifecycleWarnings: function() {}, - recordDeprecationWarnings: function(fiber, instance) {}, recordUnsafeLifecycleWarnings: function(fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function() {}, recordLegacyContextWarning: function(fiber, instance) {}, - flushLegacyContextWarning: function() {} + flushLegacyContextWarning: function() {}, + discardPendingWarnings: function() {} }; { - var LIFECYCLE_SUGGESTIONS = { - UNSAFE_componentWillMount: "componentDidMount", - UNSAFE_componentWillReceiveProps: "static getDerivedStateFromProps", - UNSAFE_componentWillUpdate: "componentDidUpdate" - }; - - var pendingComponentWillMountWarnings = []; - var pendingComponentWillReceivePropsWarnings = []; - var pendingComponentWillUpdateWarnings = []; - var pendingUnsafeLifecycleWarnings = new Map(); - var pendingLegacyContextWarning = new Map(); - - // Tracks components we have already warned about. - var didWarnAboutDeprecatedLifecycles = new Set(); - var didWarnAboutUnsafeLifecycles = new Set(); - var didWarnAboutLegacyContext = new Set(); - - var setToSortedString = function(set) { - var array = []; - set.forEach(function(value) { - array.push(value); - }); - return array.sort().join(", "); - }; - - ReactStrictModeWarnings.discardPendingWarnings = function() { - pendingComponentWillMountWarnings = []; - pendingComponentWillReceivePropsWarnings = []; - pendingComponentWillUpdateWarnings = []; - pendingUnsafeLifecycleWarnings = new Map(); - pendingLegacyContextWarning = new Map(); - }; - - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { - pendingUnsafeLifecycleWarnings.forEach(function( - lifecycleWarningsMap, - strictRoot - ) { - var lifecyclesWarningMessages = []; - - Object.keys(lifecycleWarningsMap).forEach(function(lifecycle) { - var lifecycleWarnings = lifecycleWarningsMap[lifecycle]; - if (lifecycleWarnings.length > 0) { - var componentNames = new Set(); - lifecycleWarnings.forEach(function(fiber) { - componentNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - - var formatted = lifecycle.replace("UNSAFE_", ""); - var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle]; - var sortedComponentNames = setToSortedString(componentNames); - - lifecyclesWarningMessages.push( - formatted + - ": Please update the following components to use " + - (suggestion + " instead: " + sortedComponentNames) - ); - } - }); - - if (lifecyclesWarningMessages.length > 0) { - var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - - warningWithoutStack$1( - false, - "Unsafe lifecycle methods were found within a strict-mode tree:%s" + - "\n\n%s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-strict-mode-warnings", - strictRootComponentStack, - lifecyclesWarningMessages.join("\n\n") - ); - } - }); - - pendingUnsafeLifecycleWarnings = new Map(); - }; - var findStrictRoot = function(fiber) { var maybeStrictRoot = null; @@ -5970,173 +5865,258 @@ var ReactStrictModeWarnings = { return maybeStrictRoot; }; - ReactStrictModeWarnings.flushPendingDeprecationWarnings = function() { - if (pendingComponentWillMountWarnings.length > 0) { - var uniqueNames = new Set(); - pendingComponentWillMountWarnings.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); + var setToSortedString = function(set) { + var array = []; + set.forEach(function(value) { + array.push(value); + }); + return array.sort().join(", "); + }; - var sortedNames = setToSortedString(uniqueNames); + var pendingComponentWillMountWarnings = []; + var pendingUNSAFE_ComponentWillMountWarnings = []; + var pendingComponentWillReceivePropsWarnings = []; + var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + var pendingComponentWillUpdateWarnings = []; + var pendingUNSAFE_ComponentWillUpdateWarnings = []; - lowPriorityWarning$1( - false, - "componentWillMount is deprecated and will be removed in the next major version. " + - "Use componentDidMount instead. As a temporary workaround, " + - "you can rename to UNSAFE_componentWillMount." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - sortedNames - ); + // Tracks components we have already warned about. + var didWarnAboutUnsafeLifecycles = new Set(); - pendingComponentWillMountWarnings = []; - } - - if (pendingComponentWillReceivePropsWarnings.length > 0) { - var _uniqueNames = new Set(); - pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { - _uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); - - var _sortedNames = setToSortedString(_uniqueNames); - - lowPriorityWarning$1( - false, - "componentWillReceiveProps is deprecated and will be removed in the next major version. " + - "Use static getDerivedStateFromProps instead." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - _sortedNames - ); - - pendingComponentWillReceivePropsWarnings = []; - } - - if (pendingComponentWillUpdateWarnings.length > 0) { - var _uniqueNames2 = new Set(); - pendingComponentWillUpdateWarnings.forEach(function(fiber) { - _uniqueNames2.add(getComponentName(fiber.type) || "Component"); - didWarnAboutDeprecatedLifecycles.add(fiber.type); - }); - - var _sortedNames2 = setToSortedString(_uniqueNames2); - - lowPriorityWarning$1( - false, - "componentWillUpdate is deprecated and will be removed in the next major version. " + - "Use componentDidUpdate instead. As a temporary workaround, " + - "you can rename to UNSAFE_componentWillUpdate." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-async-component-lifecycle-hooks", - _sortedNames2 - ); - - pendingComponentWillUpdateWarnings = []; - } - }; - - ReactStrictModeWarnings.recordDeprecationWarnings = function( + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( fiber, instance ) { // Dedup strategy: Warn once per component. - if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) { + if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } - // Don't warn about react-lifecycles-compat polyfilled components. if ( typeof instance.componentWillMount === "function" && + // Don't warn about react-lifecycles-compat polyfilled components. instance.componentWillMount.__suppressDeprecationWarning !== true ) { pendingComponentWillMountWarnings.push(fiber); } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillMount === "function" + ) { + pendingUNSAFE_ComponentWillMountWarnings.push(fiber); + } + if ( typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true ) { pendingComponentWillReceivePropsWarnings.push(fiber); } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); + } + if ( typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true ) { pendingComponentWillUpdateWarnings.push(fiber); } + + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); + } }; - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( - fiber, - instance - ) { - var strictRoot = findStrictRoot(fiber); - if (strictRoot === null) { + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { + // We do an initial pass to gather component names + var componentWillMountUniqueNames = new Set(); + if (pendingComponentWillMountWarnings.length > 0) { + pendingComponentWillMountWarnings.forEach(function(fiber) { + componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillMountWarnings = []; + } + + var UNSAFE_componentWillMountUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { + pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { + UNSAFE_componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillMountWarnings = []; + } + + var componentWillReceivePropsUniqueNames = new Set(); + if (pendingComponentWillReceivePropsWarnings.length > 0) { + pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { + componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingComponentWillReceivePropsWarnings = []; + } + + var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { + UNSAFE_componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + } + + var componentWillUpdateUniqueNames = new Set(); + if (pendingComponentWillUpdateWarnings.length > 0) { + pendingComponentWillUpdateWarnings.forEach(function(fiber) { + componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingComponentWillUpdateWarnings = []; + } + + var UNSAFE_componentWillUpdateUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { + pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { + UNSAFE_componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + + pendingUNSAFE_ComponentWillUpdateWarnings = []; + } + + // Finally, we flush all the warnings + // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' + if (UNSAFE_componentWillMountUniqueNames.size > 0) { + var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); warningWithoutStack$1( false, - "Expected to find a StrictMode component in a strict mode tree. " + - "This error is likely caused by a bug in React. Please file an issue." + "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "\nPlease update the following components: %s", + sortedNames ); - return; } - // Dedup strategy: Warn once per component. - // This is difficult to track any other way since component names - // are often vague and are likely to collide between 3rd party libraries. - // An expand property is probably okay to use here since it's DEV-only, - // and will only be set in the event of serious warnings. - if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { - return; + if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames = setToSortedString( + UNSAFE_componentWillReceivePropsUniqueNames + ); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, " + + "refactor your code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" + + "\nPlease update the following components: %s", + _sortedNames + ); } - var warningsForRoot = void 0; - if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) { - warningsForRoot = { - UNSAFE_componentWillMount: [], - UNSAFE_componentWillReceiveProps: [], - UNSAFE_componentWillUpdate: [] - }; - - pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot); - } else { - warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot); + if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { + var _sortedNames2 = setToSortedString( + UNSAFE_componentWillUpdateUniqueNames + ); + warningWithoutStack$1( + false, + "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "\nPlease update the following components: %s", + _sortedNames2 + ); } - var unsafeLifecycles = []; - if ( - (typeof instance.componentWillMount === "function" && - instance.componentWillMount.__suppressDeprecationWarning !== true) || - typeof instance.UNSAFE_componentWillMount === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillMount"); - } - if ( - (typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== - true) || - typeof instance.UNSAFE_componentWillReceiveProps === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillReceiveProps"); + if (componentWillMountUniqueNames.size > 0) { + var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); + + lowPriorityWarning$1( + false, + "componentWillMount has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames3 + ); } - if ( - (typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true) || - typeof instance.UNSAFE_componentWillUpdate === "function" - ) { - unsafeLifecycles.push("UNSAFE_componentWillUpdate"); + + if (componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames4 = setToSortedString( + componentWillReceivePropsUniqueNames + ); + + lowPriorityWarning$1( + false, + "componentWillReceiveProps has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, refactor your " + + "code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n" + + "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames4 + ); } - if (unsafeLifecycles.length > 0) { - unsafeLifecycles.forEach(function(lifecycle) { - warningsForRoot[lifecycle].push(fiber); - }); + if (componentWillUpdateUniqueNames.size > 0) { + var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); + + lowPriorityWarning$1( + false, + "componentWillUpdate has been renamed, and is not recommended for use. " + + "See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " + + "this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames5 + ); } }; + var pendingLegacyContextWarning = new Map(); + + // Tracks components we have already warned about. + var didWarnAboutLegacyContext = new Set(); + ReactStrictModeWarnings.recordLegacyContextWarning = function( fiber, instance @@ -6185,105 +6165,523 @@ var ReactStrictModeWarnings = { warningWithoutStack$1( false, "Legacy context API has been detected within a strict-mode tree: %s" + + "\n\nThe old API will be supported in all 16.x releases, but applications " + + "using it should migrate to the new version." + "\n\nPlease update the following components: %s" + "\n\nLearn more about this warning here:" + - "\nhttps://fb.me/react-strict-mode-warnings", + "\nhttps://fb.me/react-legacy-context", strictRootComponentStack, sortedNames ); }); }; + + ReactStrictModeWarnings.discardPendingWarnings = function() { + pendingComponentWillMountWarnings = []; + pendingUNSAFE_ComponentWillMountWarnings = []; + pendingComponentWillReceivePropsWarnings = []; + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + pendingComponentWillUpdateWarnings = []; + pendingUNSAFE_ComponentWillUpdateWarnings = []; + pendingLegacyContextWarning = new Map(); + }; } -function resolveDefaultProps(Component, baseProps) { - if (Component && Component.defaultProps) { - // Resolve default props. Taken from ReactElement - var props = Object.assign({}, baseProps); - var defaultProps = Component.defaultProps; - for (var propName in defaultProps) { - if (props[propName] === undefined) { - props[propName] = defaultProps[propName]; - } - } - return props; +// Resolves type to a family. + +// Used by React Refresh runtime through DevTools Global Hook. + +var resolveFamily = null; +// $FlowFixMe Flow gets confused by a WeakSet feature check below. +var failedBoundaries = null; + +var setRefreshHandler = function(handler) { + { + resolveFamily = handler; } - return baseProps; -} +}; -function readLazyComponentType(lazyComponent) { - var status = lazyComponent._status; - var result = lazyComponent._result; - switch (status) { - case Resolved: { - var Component = result; - return Component; - } - case Rejected: { - var error = result; - throw error; - } - case Pending: { - var thenable = result; - throw thenable; +function resolveFunctionForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; } - default: { - lazyComponent._status = Pending; - var ctor = lazyComponent._ctor; - var _thenable = ctor(); - _thenable.then( - function(moduleObject) { - if (lazyComponent._status === Pending) { - var defaultExport = moduleObject.default; - { - if (defaultExport === undefined) { - warning$1( - false, - "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + - "const MyComponent = lazy(() => import('./MyComponent'))", - moduleObject - ); - } - } - lazyComponent._status = Resolved; - lazyComponent._result = defaultExport; - } - }, - function(error) { - if (lazyComponent._status === Pending) { - lazyComponent._status = Rejected; - lazyComponent._result = error; - } - } - ); - // Handle synchronous thenables. - switch (lazyComponent._status) { - case Resolved: - return lazyComponent._result; - case Rejected: - throw lazyComponent._result; - } - lazyComponent._result = _thenable; - throw _thenable; + var family = resolveFamily(type); + if (family === undefined) { + return type; } + // Use the latest known implementation. + return family.current; } } -var valueCursor = createCursor(null); - -var rendererSigil = void 0; -{ - // Use this to detect multiple renderers using the same context - rendererSigil = {}; +function resolveClassForHotReloading(type) { + // No implementation differences. + return resolveFunctionForHotReloading(type); } -var currentlyRenderingFiber = null; -var lastContextDependency = null; -var lastContextWithAllBitsObserved = null; - -var isDisallowedContextReadInDEV = false; +function resolveForwardRefForHotReloading(type) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return type; + } + var family = resolveFamily(type); + if (family === undefined) { + // Check if we're dealing with a real forwardRef. Don't want to crash early. + if ( + type !== null && + type !== undefined && + typeof type.render === "function" + ) { + // ForwardRef is special because its resolved .type is an object, + // but it's possible that we only have its inner render function in the map. + // If that inner render function is different, we'll build a new forwardRef type. + var currentRender = resolveFunctionForHotReloading(type.render); + if (type.render !== currentRender) { + var syntheticType = { + $$typeof: REACT_FORWARD_REF_TYPE, + render: currentRender + }; + if (type.displayName !== undefined) { + syntheticType.displayName = type.displayName; + } + return syntheticType; + } + } + return type; + } + // Use the latest known implementation. + return family.current; + } +} + +function isCompatibleFamilyForHotReloading(fiber, element) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return false; + } + + var prevType = fiber.elementType; + var nextType = element.type; + + // If we got here, we know types aren't === equal. + var needsCompareFamilies = false; + + var $$typeofNextType = + typeof nextType === "object" && nextType !== null + ? nextType.$$typeof + : null; + + switch (fiber.tag) { + case ClassComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } + break; + } + case FunctionComponent: { + if (typeof nextType === "function") { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + // We don't know the inner type yet. + // We're going to assume that the lazy inner type is stable, + // and so it is sufficient to avoid reconciling it away. + // We're not going to unwrap or actually use the new lazy type. + needsCompareFamilies = true; + } + break; + } + case ForwardRef: { + if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + break; + } + case MemoComponent: + case SimpleMemoComponent: { + if ($$typeofNextType === REACT_MEMO_TYPE) { + // TODO: if it was but can no longer be simple, + // we shouldn't set this. + needsCompareFamilies = true; + } else if ($$typeofNextType === REACT_LAZY_TYPE) { + needsCompareFamilies = true; + } + break; + } + default: + return false; + } + + // Check if both types have a family and it's the same one. + if (needsCompareFamilies) { + // Note: memo() and forwardRef() we'll compare outer rather than inner type. + // This means both of them need to be registered to preserve state. + // If we unwrapped and compared the inner types for wrappers instead, + // then we would risk falsely saying two separate memo(Foo) + // calls are equivalent because they wrap the same Foo function. + var prevFamily = resolveFamily(prevType); + if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { + return true; + } + } + return false; + } +} + +function markFailedErrorBoundaryForHotReloading(fiber) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + if (typeof WeakSet !== "function") { + return; + } + if (failedBoundaries === null) { + failedBoundaries = new WeakSet(); + } + failedBoundaries.add(fiber); + } +} + +var scheduleRefresh = function(root, update) { + { + if (resolveFamily === null) { + // Hot reloading is disabled. + return; + } + var _staleFamilies = update.staleFamilies, + _updatedFamilies = update.updatedFamilies; + + flushPassiveEffects(); + flushSync(function() { + scheduleFibersWithFamiliesRecursively( + root.current, + _updatedFamilies, + _staleFamilies + ); + }); + } +}; + +var scheduleRoot = function(root, element) { + { + if (root.context !== emptyContextObject) { + // Super edge case: root has a legacy _renderSubtree context + // but we don't know the parentComponent so we can't pass it. + // Just ignore. We'll delete this with _renderSubtree code path later. + return; + } + flushPassiveEffects(); + updateContainerAtExpirationTime(element, root, null, Sync, null); + } +}; + +function scheduleFibersWithFamiliesRecursively( + fiber, + updatedFamilies, + staleFamilies +) { + { + var alternate = fiber.alternate, + child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; + + var candidateType = null; + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + default: + break; + } + + if (resolveFamily === null) { + throw new Error("Expected resolveFamily to be set during hot reload."); + } + + var needsRender = false; + var needsRemount = false; + if (candidateType !== null) { + var family = resolveFamily(candidateType); + if (family !== undefined) { + if (staleFamilies.has(family)) { + needsRemount = true; + } else if (updatedFamilies.has(family)) { + needsRender = true; + } + } + } + if (failedBoundaries !== null) { + if ( + failedBoundaries.has(fiber) || + (alternate !== null && failedBoundaries.has(alternate)) + ) { + needsRemount = true; + } + } + + if (needsRemount) { + fiber._debugNeedsRemount = true; + } + if (needsRemount || needsRender) { + scheduleWork(fiber, Sync); + } + if (child !== null && !needsRemount) { + scheduleFibersWithFamiliesRecursively( + child, + updatedFamilies, + staleFamilies + ); + } + if (sibling !== null) { + scheduleFibersWithFamiliesRecursively( + sibling, + updatedFamilies, + staleFamilies + ); + } + } +} + +var findHostInstancesForRefresh = function(root, families) { + { + var hostInstances = new Set(); + var types = new Set( + families.map(function(family) { + return family.current; + }) + ); + findHostInstancesForMatchingFibersRecursively( + root.current, + types, + hostInstances + ); + return hostInstances; + } +}; + +function findHostInstancesForMatchingFibersRecursively( + fiber, + types, + hostInstances +) { + { + var child = fiber.child, + sibling = fiber.sibling, + tag = fiber.tag, + type = fiber.type; + + var candidateType = null; + switch (tag) { + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + default: + break; + } + + var didMatch = false; + if (candidateType !== null) { + if (types.has(candidateType)) { + didMatch = true; + } + } + + if (didMatch) { + // We have a match. This only drills down to the closest host components. + // There's no need to search deeper because for the purpose of giving + // visual feedback, "flashing" outermost parent rectangles is sufficient. + findHostInstancesForFiberShallowly(fiber, hostInstances); + } else { + // If there's no match, maybe there will be one further down in the child tree. + if (child !== null) { + findHostInstancesForMatchingFibersRecursively( + child, + types, + hostInstances + ); + } + } + + if (sibling !== null) { + findHostInstancesForMatchingFibersRecursively( + sibling, + types, + hostInstances + ); + } + } +} + +function findHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var foundHostInstances = findChildHostInstancesForFiberShallowly( + fiber, + hostInstances + ); + if (foundHostInstances) { + return; + } + // If we didn't find any host children, fallback to closest host parent. + var node = fiber; + while (true) { + switch (node.tag) { + case HostComponent: + hostInstances.add(node.stateNode); + return; + case HostPortal: + hostInstances.add(node.stateNode.containerInfo); + return; + case HostRoot: + hostInstances.add(node.stateNode.containerInfo); + return; + } + if (node.return === null) { + throw new Error("Expected to reach root first."); + } + node = node.return; + } + } +} + +function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { + { + var node = fiber; + var foundHostInstances = false; + while (true) { + if (node.tag === HostComponent) { + // We got a match. + foundHostInstances = true; + hostInstances.add(node.stateNode); + // There may still be more, so keep searching. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === fiber) { + return foundHostInstances; + } + while (node.sibling === null) { + if (node.return === null || node.return === fiber) { + return foundHostInstances; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + } + return false; +} + +function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + // Resolve default props. Taken from ReactElement + var props = Object.assign({}, baseProps); + var defaultProps = Component.defaultProps; + for (var propName in defaultProps) { + if (props[propName] === undefined) { + props[propName] = defaultProps[propName]; + } + } + return props; + } + return baseProps; +} + +function readLazyComponentType(lazyComponent) { + var status = lazyComponent._status; + var result = lazyComponent._result; + switch (status) { + case Resolved: { + var Component = result; + return Component; + } + case Rejected: { + var error = result; + throw error; + } + case Pending: { + var thenable = result; + throw thenable; + } + default: { + lazyComponent._status = Pending; + var ctor = lazyComponent._ctor; + var _thenable = ctor(); + _thenable.then( + function(moduleObject) { + if (lazyComponent._status === Pending) { + var defaultExport = moduleObject.default; + { + if (defaultExport === undefined) { + warning$1( + false, + "lazy: Expected the result of a dynamic import() call. " + + "Instead received: %s\n\nYour code should look like: \n " + + "const MyComponent = lazy(() => import('./MyComponent'))", + moduleObject + ); + } + } + lazyComponent._status = Resolved; + lazyComponent._result = defaultExport; + } + }, + function(error) { + if (lazyComponent._status === Pending) { + lazyComponent._status = Rejected; + lazyComponent._result = error; + } + } + ); + // Handle synchronous thenables. + switch (lazyComponent._status) { + case Resolved: + return lazyComponent._result; + case Rejected: + throw lazyComponent._result; + } + lazyComponent._result = _thenable; + throw _thenable; + } + } +} + +var valueCursor = createCursor(null); + +var rendererSigil = void 0; +{ + // Use this to detect multiple renderers using the same context + rendererSigil = {}; +} + +var currentlyRenderingFiber = null; +var lastContextDependency = null; +var lastContextWithAllBitsObserved = null; + +var isDisallowedContextReadInDEV = false; -function resetContextDependences() { +function resetContextDependencies() { // This is called right before React yields execution, to ensure `readContext` // cannot be called outside the render phase. currentlyRenderingFiber = null; @@ -6428,11 +6826,11 @@ function propagateContextChange( var nextFiber = void 0; // Visit this fiber. - var list = fiber.contextDependencies; + var list = fiber.dependencies; if (list !== null) { nextFiber = fiber.child; - var dependency = list.first; + var dependency = list.firstContext; while (dependency !== null) { // Check if the context matches. if ( @@ -6443,7 +6841,7 @@ function propagateContextChange( if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate(renderExpirationTime); + var update = createUpdate(renderExpirationTime, null); 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 @@ -6539,17 +6937,18 @@ function prepareToReadContext(workInProgress, renderExpirationTime) { lastContextDependency = null; lastContextWithAllBitsObserved = null; - var currentDependencies = workInProgress.contextDependencies; - if ( - currentDependencies !== null && - currentDependencies.expirationTime >= renderExpirationTime - ) { - // Context list has a pending update. Mark that this fiber performed work. - markWorkInProgressReceivedUpdate(); + var dependencies = workInProgress.dependencies; + if (dependencies !== null) { + var firstContext = dependencies.firstContext; + if (firstContext !== null) { + if (dependencies.expirationTime >= renderExpirationTime) { + // Context list has a pending update. Mark that this fiber performed work. + markWorkInProgressReceivedUpdate(); + } + // Reset the work-in-progress list + dependencies.firstContext = null; + } } - - // Reset the work-in-progress list - workInProgress.contextDependencies = null; } function readContext(context, observedBits) { @@ -6594,16 +6993,20 @@ function readContext(context, observedBits) { (function() { if (!(currentlyRenderingFiber !== null)) { throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); } })(); // This is the first dependency for this component. Create a new list. lastContextDependency = contextItem; - currentlyRenderingFiber.contextDependencies = { - first: contextItem, - expirationTime: NoWork + currentlyRenderingFiber.dependencies = { + expirationTime: NoWork, + firstContext: contextItem, + listeners: null, + responders: null }; } else { // Append a new context item. @@ -6743,9 +7146,10 @@ function cloneUpdateQueue(currentQueue) { return queue; } -function createUpdate(expirationTime) { - return { +function createUpdate(expirationTime, suspenseConfig) { + var update = { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: UpdateState, payload: null, @@ -6754,6 +7158,10 @@ function createUpdate(expirationTime) { next: null, nextEffect: null }; + { + update.priority = getCurrentPriorityLevel(); + } + return update; } function appendUpdateToQueue(queue, update) { @@ -7006,7 +7414,7 @@ function processUpdateQueue( // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTime(updateExpirationTime); + markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. resultState = getStateFromUpdate( @@ -7120,8 +7528,10 @@ function callCallback(callback, context) { (function() { if (!(typeof callback === "function")) { throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ) ); } })(); @@ -7175,6 +7585,12 @@ function commitUpdateEffects(effect, instance) { } } +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; + +function requestCurrentSuspenseConfig() { + return ReactCurrentBatchConfig.suspense; +} + var fakeInternalInstance = {}; var isArray$1 = Array.isArray; @@ -7248,7 +7664,9 @@ var didWarnAboutInvalidateContextType = void 0; (function() { { throw ReactError( - "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + Error( + "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + ) ); } })(); @@ -7301,9 +7719,14 @@ var classComponentUpdater = { enqueueSetState: function(inst, payload, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.payload = payload; if (callback !== undefined && callback !== null) { { @@ -7312,16 +7735,23 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.tag = ReplaceState; update.payload = payload; @@ -7332,16 +7762,23 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, fiber); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); update.tag = ForceUpdate; if (callback !== undefined && callback !== null) { @@ -7351,7 +7788,9 @@ var classComponentUpdater = { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); } @@ -7934,11 +8373,6 @@ function mountClassInstance( } if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( - workInProgress, - instance - ); - ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -7946,7 +8380,7 @@ function mountClassInstance( } if (warnAboutDeprecatedLifecycles) { - ReactStrictModeWarnings.recordDeprecationWarnings( + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance ); @@ -8354,7 +8788,9 @@ var warnForMissingKey = function(child) {}; (function() { if (!(typeof child._store === "object")) { throw ReactError( - "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." + Error( + "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8416,7 +8852,9 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!(ownerFiber.tag === ClassComponent)) { throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); } })(); @@ -8425,9 +8863,11 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!inst) { throw ReactError( - "Missing owner for string ref " + - mixedRef + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + mixedRef + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -8459,16 +8899,20 @@ function coerceRef(returnFiber, current$$1, element) { (function() { if (!(typeof mixedRef === "string")) { throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); } })(); (function() { if (!element._owner) { throw ReactError( - "Element ref was specified as a string (" + - mixedRef + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + mixedRef + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } })(); @@ -8489,12 +8933,14 @@ function throwOnInvalidObjectType(returnFiber, newChild) { (function() { { throw ReactError( - "Objects are not valid as a React child (found: " + - (Object.prototype.toString.call(newChild) === "[object Object]" - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + - addendum + Error( + "Objects are not valid as a React child (found: " + + (Object.prototype.toString.call(newChild) === "[object Object]" + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + + addendum + ) ); } })(); @@ -9164,7 +9610,9 @@ function ChildReconciler(shouldTrackSideEffects) { (function() { if (!(typeof iteratorFn === "function")) { throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -9219,7 +9667,7 @@ function ChildReconciler(shouldTrackSideEffects) { var newChildren = iteratorFn.call(newChildrenIterable); (function() { if (!(newChildren != null)) { - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); } })(); @@ -9597,8 +10045,10 @@ function ChildReconciler(shouldTrackSideEffects) { (function() { { throw ReactError( - (Component.displayName || Component.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (Component.displayName || Component.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) ); } })(); @@ -9619,7 +10069,7 @@ var mountChildFibers = ChildReconciler(false); function cloneChildFibers(current$$1, workInProgress) { (function() { if (!(current$$1 === null || workInProgress.child === current$$1.child)) { - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); } })(); @@ -9648,6 +10098,15 @@ function cloneChildFibers(current$$1, workInProgress) { newChild.sibling = null; } +// Reset a workInProgress child set to prepare it for a second pass. +function resetChildFibers(workInProgress, renderExpirationTime) { + var child = workInProgress.child; + while (child !== null) { + resetWorkInProgress(child, renderExpirationTime); + child = child.sibling; + } +} + var NO_CONTEXT = {}; var contextStackCursor$1 = createCursor(NO_CONTEXT); @@ -9658,7 +10117,9 @@ function requiredContext(c) { (function() { if (!(c !== NO_CONTEXT)) { throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -9717,46 +10178,188 @@ function pushHostContext(fiber) { push(contextStackCursor$1, nextContext, fiber); } -function pushHostContextForEventComponent(fiber) { - var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContextForEventComponent(context); - - // Don't push this Fiber's context unless it's unique. - if (context === nextContext) { +function popHostContext(fiber) { + // Do not pop unless this Fiber provided the current context. + // pushHostContext() only pushes Fibers that provide unique contexts. + if (contextFiberStackCursor.current !== fiber) { return; } - // Track the context and the Fiber that provided it. - // This enables us to pop only Fibers that provide unique contexts. - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, nextContext, fiber); + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); } -function pushHostContextForEventTarget(fiber) { - var context = requiredContext(contextStackCursor$1.current); - var eventTargetType = fiber.type.type; - var nextContext = getChildHostContextForEventTarget(context, eventTargetType); +var DefaultSuspenseContext = 0; - // Don't push this Fiber's context unless it's unique. - if (context === nextContext) { - return; +// The Suspense Context is split into two parts. The lower bits is +// inherited deeply down the subtree. The upper bits only affect +// this immediate suspense boundary and gets reset each new +// boundary or suspense list. +var SubtreeSuspenseContextMask = 1; + +// Subtree Flags: + +// InvisibleParentSuspenseContext indicates that one of our parent Suspense +// boundaries is not currently showing visible main content. +// Either because it is already showing a fallback or is not mounted at all. +// We can use this to determine if it is desirable to trigger a fallback at +// the parent. If not, then we might need to trigger undesirable boundaries +// and/or suspend the commit to avoid hiding the parent content. +var InvisibleParentSuspenseContext = 1; + +// Shallow Flags: + +// ForceSuspenseFallback can be used by SuspenseList to force newly added +// items into their fallback state during one of the render passes. +var ForceSuspenseFallback = 2; + +var suspenseStackCursor = createCursor(DefaultSuspenseContext); + +function hasSuspenseContext(parentContext, flag) { + return (parentContext & flag) !== 0; +} + +function setDefaultShallowSuspenseContext(parentContext) { + return parentContext & SubtreeSuspenseContextMask; +} + +function setShallowSuspenseContext(parentContext, shallowContext) { + return (parentContext & SubtreeSuspenseContextMask) | shallowContext; +} + +function addSubtreeSuspenseContext(parentContext, subtreeContext) { + return parentContext | subtreeContext; +} + +function pushSuspenseContext(fiber, newContext) { + push(suspenseStackCursor, newContext, fiber); +} + +function popSuspenseContext(fiber) { + pop(suspenseStackCursor, fiber); +} + +// TODO: This is now an empty object. Should we switch this to a boolean? +// Alternatively we can make this use an effect tag similar to SuspenseList. + +function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { + // If it was the primary children that just suspended, capture and render the + var nextState = workInProgress.memoizedState; + if (nextState !== null) { + return false; + } + var props = workInProgress.memoizedProps; + // In order to capture, the Suspense component must have a fallback prop. + if (props.fallback === undefined) { + return false; + } + // Regular boundaries always capture. + if (props.unstable_avoidThisFallback !== true) { + return true; + } + // If it's a boundary we should avoid, then we prefer to bubble up to the + // parent boundary if it is currently invisible. + if (hasInvisibleParent) { + return false; } + // If the parent is not able to handle it, we must handle it. + return true; +} - // Track the context and the Fiber that provided it. - // This enables us to pop only Fibers that provide unique contexts. - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, nextContext, fiber); +function findFirstSuspended(row) { + var node = row; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + return node; + } + } else if ( + node.tag === SuspenseListComponent && + // revealOrder undefined can't be trusted because it don't + // keep track of whether it suspended or not. + node.memoizedProps.revealOrder !== undefined + ) { + var didSuspend = (node.effectTag & DidCapture) !== NoEffect; + if (didSuspend) { + return node; + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) { + return null; + } + while (node.sibling === null) { + if (node.return === null || node.return === row) { + return null; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; } -function popHostContext(fiber) { - // Do not pop unless this Fiber provided the current context. - // pushHostContext() only pushes Fibers that provide unique contexts. - if (contextFiberStackCursor.current !== fiber) { - return; +var currentlyRenderingFiber$2 = null; +var currentListenerHookIndex = 0; + +function prepareToReadListenerHooks(workInProgress) { + currentlyRenderingFiber$2 = workInProgress; + currentListenerHookIndex = 0; +} + +function getListenerHooks() { + var listeners = void 0; + var dependencies = currentlyRenderingFiber$2.dependencies; + if (dependencies === null) { + dependencies = currentlyRenderingFiber$2.dependencies = { + expirationTime: NoWork, + firstContext: null, + listeners: [], + responders: null + }; + } + listeners = dependencies.listeners; + if (listeners === null) { + dependencies.listeners = listeners = []; } + return listeners; +} - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); +function updateListenerHook(responder, props) { + var listeners = getListenerHooks(); + if (listeners.length === currentListenerHookIndex) { + listeners.push({ + responder: responder, + props: props + }); + currentListenerHookIndex++; + } else { + var currentListenerHook = listeners[currentListenerHookIndex++]; + currentListenerHook.responder = responder; + currentListenerHook.props = props; + } +} + +function createResponderInstance( + responder, + responderProps, + responderState, + target, + fiber +) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState, + target: target + }; } var NoEffect$1 = /* */ 0; @@ -9916,7 +10519,9 @@ function throwInvalidHookError() { (function() { { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } })(); @@ -10097,7 +10702,9 @@ function renderWithHooks( (function() { if (!!didRenderTooFewHooks) { throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); } })(); @@ -10185,7 +10792,7 @@ function updateWorkInProgressHook() { (function() { if (!(nextCurrentHook !== null)) { throw ReactError( - "Rendered more hooks than during the previous render." + Error("Rendered more hooks than during the previous render.") ); } })(); @@ -10253,7 +10860,9 @@ function updateReducer(reducer, initialArg, init) { (function() { if (!(queue !== null)) { throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); } })(); @@ -10286,7 +10895,7 @@ function updateReducer(reducer, initialArg, init) { } hook.memoizedState = newState; - // Don't persist the state accumlated from the render phase updates to + // Don't persist the state accumulated from the render phase updates to // the base state unless the queue is empty. // TODO: Not sure if this is the desired semantics, but it's what we // do for gDSFP. I can't remember why. @@ -10352,7 +10961,10 @@ function updateReducer(reducer, initialArg, init) { // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTime(updateExpirationTime); + markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ); // Process this update. if (_update.eagerReducer === reducer) { @@ -10485,6 +11097,12 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { } function mountEffect(create, deps) { + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } return mountEffectImpl( Update | Passive, UnmountPassive | MountPassive, @@ -10494,6 +11112,12 @@ function mountEffect(create, deps) { } function updateEffect(create, deps) { + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } return updateEffectImpl( Update | Passive, UnmountPassive | MountPassive, @@ -10647,7 +11271,9 @@ function dispatchAction(fiber, queue, action) { (function() { if (!(numberOfReRenders < RE_RENDER_LIMIT)) { throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); } })(); @@ -10674,11 +11300,15 @@ function dispatchAction(fiber, queue, action) { didScheduleRenderPhaseUpdate = true; var update = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, next: null }; + { + update.priority = getCurrentPriorityLevel(); + } if (renderPhaseUpdates === null) { renderPhaseUpdates = new Map(); } @@ -10694,19 +11324,31 @@ function dispatchAction(fiber, queue, action) { lastRenderPhaseUpdate.next = update; } } else { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } var currentTime = requestCurrentTime(); - var _expirationTime = computeExpirationForFiber(currentTime, fiber); + var _suspenseConfig = requestCurrentSuspenseConfig(); + var _expirationTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); var _update2 = { expirationTime: _expirationTime, + suspenseConfig: _suspenseConfig, action: action, eagerReducer: null, eagerState: null, next: null }; + { + _update2.priority = getCurrentPriorityLevel(); + } + // Append the update to the end of the list. var _last = queue.last; if (_last === null) { @@ -10762,10 +11404,9 @@ function dispatchAction(fiber, queue, action) { } } { - // jest isn't a 'global', it's just exposed to tests via a wrapped function - // further, this isn't a test file, so flow doesn't recognize the symbol. So... - // $FlowExpectedError - because requirements don't give a damn about your type sigs. + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(fiber); warnIfNotCurrentlyActingUpdatesInDev(fiber); } } @@ -10785,7 +11426,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }; var HooksDispatcherOnMountInDEV = null; @@ -10891,6 +11533,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + mountHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -10965,6 +11612,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + updateHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -11039,6 +11691,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); return updateDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + updateHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -11124,6 +11781,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); mountHookTypesDev(); return mountDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + warnInvalidHookAccess(); + mountHookTypesDev(); + updateListenerHook(responder, props); } }; @@ -11209,6 +11872,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); updateHookTypesDev(); return updateDebugValue(value, formatterFn); + }, + useListener: function(responder, props) { + currentHookNameInDev = "useListener"; + warnInvalidHookAccess(); + updateHookTypesDev(); + updateListenerHook(responder, props); } }; } @@ -11478,7 +12147,9 @@ function prepareToHydrateHostInstance( (function() { { throw ReactError( - "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11508,7 +12179,9 @@ function prepareToHydrateHostTextInstance(fiber) { (function() { { throw ReactError( - "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11558,7 +12231,9 @@ function skipPastDehydratedSuspenseInstance(fiber) { (function() { { throw ReactError( - "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11567,7 +12242,9 @@ function skipPastDehydratedSuspenseInstance(fiber) { (function() { if (!suspenseInstance) { throw ReactError( - "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -11655,6 +12332,9 @@ var didWarnAboutGetDerivedStateOnFunctionComponent = void 0; var didWarnAboutFunctionRefs = void 0; var didWarnAboutReassigningProps = void 0; var didWarnAboutMaxDuration = void 0; +var didWarnAboutRevealOrder = void 0; +var didWarnAboutTailOptions = void 0; +var didWarnAboutDefaultPropsOnFunctionComponent = void 0; { didWarnAboutBadClass = {}; @@ -11664,6 +12344,9 @@ var didWarnAboutMaxDuration = void 0; didWarnAboutFunctionRefs = {}; didWarnAboutReassigningProps = false; didWarnAboutMaxDuration = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; } function reconcileChildren( @@ -11765,6 +12448,9 @@ function updateForwardRef( // The rest is a fork of updateFunctionComponent var nextChildren = void 0; prepareToReadContext(workInProgress, renderExpirationTime); + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } { ReactCurrentOwner$3.current = workInProgress; setCurrentPhase("render"); @@ -11783,6 +12469,9 @@ function updateForwardRef( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } nextChildren = renderWithHooks( current$$1, workInProgress, @@ -12067,6 +12756,9 @@ function updateFunctionComponent( var nextChildren = void 0; prepareToReadContext(workInProgress, renderExpirationTime); + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } { ReactCurrentOwner$3.current = workInProgress; setCurrentPhase("render"); @@ -12085,6 +12777,9 @@ function updateFunctionComponent( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } nextChildren = renderWithHooks( current$$1, workInProgress, @@ -12338,7 +13033,9 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { (function() { if (!(updateQueue !== null)) { throw ReactError( - "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." + 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." + ) ); } })(); @@ -12436,10 +13133,13 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { // Check the host config to see if the children are offscreen/hidden. if ( - renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps) ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. workInProgress.expirationTime = workInProgress.childExpirationTime = Never; return null; @@ -12581,10 +13281,12 @@ function mountLazyComponent( (function() { { throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ) ); } })(); @@ -12673,7 +13375,9 @@ function mountIndeterminateComponent( var context = getMaskedContext(workInProgress, unmaskedContext); prepareToReadContext(workInProgress, renderExpirationTime); - + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } var value = void 0; { @@ -12787,6 +13491,9 @@ function mountIndeterminateComponent( ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { + if (enableFlareAPI) { + prepareToReadListenerHooks(workInProgress); + } value = renderWithHooks( null, workInProgress, @@ -12840,16 +13547,33 @@ function validateFunctionComponentInDev(workInProgress, Component) { } } - if (typeof Component.getDerivedStateFromProps === "function") { + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { var componentName = getComponentName(Component) || "Unknown"; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) { + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { warningWithoutStack$1( false, - "%s: Function components do not support getDerivedStateFromProps.", + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", componentName ); - didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true; + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } + + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + warningWithoutStack$1( + false, + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; } } @@ -12857,19 +13581,31 @@ function validateFunctionComponentInDev(workInProgress, Component) { typeof Component.contextType === "object" && Component.contextType !== null ) { - var _componentName2 = getComponentName(Component) || "Unknown"; + var _componentName3 = getComponentName(Component) || "Unknown"; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName2]) { + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { warningWithoutStack$1( false, "%s: Function components do not support contextType.", - _componentName2 + _componentName3 ); - didWarnAboutContextTypeOnFunctionComponent[_componentName2] = true; + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; } } } +// TODO: This is now an empty object. Should we just make it a boolean? +var SUSPENDED_MARKER = {}; + +function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { + // If the context is telling us that we should show a fallback, and we're not + // already showing content, then we should show the fallback instead. + return ( + hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && + (current$$1 === null || current$$1.memoizedState !== null) + ); +} + function updateSuspenseComponent( current$$1, workInProgress, @@ -12878,32 +13614,51 @@ function updateSuspenseComponent( var mode = workInProgress.mode; var nextProps = workInProgress.pendingProps; + // This is used by DevTools to force a boundary to suspend. { if (shouldSuspend(workInProgress)) { workInProgress.effectTag |= DidCapture; } } - // We should attempt to render the primary children unless this boundary - // already suspended during this render (`alreadyCaptured` is true). - var nextState = workInProgress.memoizedState; + var suspenseContext = suspenseStackCursor.current; - var nextDidTimeout = void 0; - if ((workInProgress.effectTag & DidCapture) === NoEffect) { - // This is the first attempt. - nextState = null; - nextDidTimeout = false; - } else { + var nextState = null; + var nextDidTimeout = false; + + if ( + (workInProgress.effectTag & DidCapture) !== NoEffect || + shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) + ) { // Something in this boundary's subtree already suspended. Switch to // rendering the fallback children. - nextState = { - fallbackExpirationTime: - nextState !== null ? nextState.fallbackExpirationTime : NoWork - }; + nextState = SUSPENDED_MARKER; nextDidTimeout = true; workInProgress.effectTag &= ~DidCapture; + } else { + // Attempting the main content + if (current$$1 === null || current$$1.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); + { if ("maxDuration" in nextProps) { if (!didWarnAboutMaxDuration) { @@ -12956,6 +13711,7 @@ function updateSuspenseComponent( tryToClaimNextHydratableInstance(workInProgress); // This could've changed the tag if this was a dehydrated suspense component. if (workInProgress.tag === DehydratedSuspenseComponent) { + popSuspenseContext(workInProgress); return updateDehydratedSuspenseComponent( null, workInProgress, @@ -12976,15 +13732,21 @@ function updateSuspenseComponent( NoWork, null ); + primaryChildFragment.return = workInProgress; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var progressedState = workInProgress.memoizedState; var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child; primaryChildFragment.child = progressedPrimaryChild; + var progressedChild = progressedPrimaryChild; + while (progressedChild !== null) { + progressedChild.return = primaryChildFragment; + progressedChild = progressedChild.sibling; + } } var fallbackChildFragment = createFiberFromFragment( @@ -12993,12 +13755,12 @@ function updateSuspenseComponent( renderExpirationTime, null ); + fallbackChildFragment.return = workInProgress; primaryChildFragment.sibling = fallbackChildFragment; child = primaryChildFragment; // Skip the primary children, and continue working on the // fallback children. next = fallbackChildFragment; - child.return = next.return = workInProgress; } else { // Mount the primary children without an intermediate fragment fiber. var nextPrimaryChildren = nextProps.children; @@ -13027,9 +13789,10 @@ function updateSuspenseComponent( currentPrimaryChildFragment.pendingProps, NoWork ); + _primaryChildFragment.return = workInProgress; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var _progressedState = workInProgress.memoizedState; var _progressedPrimaryChild = _progressedState !== null @@ -13037,6 +13800,11 @@ function updateSuspenseComponent( : workInProgress.child; if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { _primaryChildFragment.child = _progressedPrimaryChild; + var _progressedChild = _progressedPrimaryChild; + while (_progressedChild !== null) { + _progressedChild.return = _primaryChildFragment; + _progressedChild = _progressedChild.sibling; + } } } @@ -13055,17 +13823,18 @@ function updateSuspenseComponent( // Clone the fallback child fragment, too. These we'll continue // working on. - var _fallbackChildFragment = (_primaryChildFragment.sibling = createWorkInProgress( + var _fallbackChildFragment = createWorkInProgress( currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime - )); + ); + _fallbackChildFragment.return = workInProgress; + _primaryChildFragment.sibling = _fallbackChildFragment; child = _primaryChildFragment; _primaryChildFragment.childExpirationTime = NoWork; // Skip the primary children, and continue working on the // fallback children. next = _fallbackChildFragment; - child.return = next.return = workInProgress; } else { // No longer suspended. Switch back to showing the primary children, // and remove the intermediate fragment fiber. @@ -13103,21 +13872,30 @@ function updateSuspenseComponent( NoWork, null ); + _primaryChildFragment2.return = workInProgress; _primaryChildFragment2.child = _currentPrimaryChild; + if (_currentPrimaryChild !== null) { + _currentPrimaryChild.return = _primaryChildFragment2; + } // Even though we're creating a new fiber, there are no new children, // because we're reusing an already mounted tree. So we don't need to // schedule a placement. // primaryChildFragment.effectTag |= Placement; - if ((workInProgress.mode & ConcurrentMode) === NoContext) { - // Outside of concurrent mode, we commit the effects from the + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched mode, we commit the effects from the var _progressedState2 = workInProgress.memoizedState; var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child; _primaryChildFragment2.child = _progressedPrimaryChild2; + var _progressedChild2 = _progressedPrimaryChild2; + while (_progressedChild2 !== null) { + _progressedChild2.return = _primaryChildFragment2; + _progressedChild2 = _progressedChild2.sibling; + } } // Because primaryChildFragment is a new fiber that we're inserting as the @@ -13134,19 +13912,20 @@ function updateSuspenseComponent( } // Create a fragment from the fallback children, too. - var _fallbackChildFragment2 = (_primaryChildFragment2.sibling = createFiberFromFragment( + var _fallbackChildFragment2 = createFiberFromFragment( _nextFallbackChildren2, mode, renderExpirationTime, null - )); + ); + _fallbackChildFragment2.return = workInProgress; + _primaryChildFragment2.sibling = _fallbackChildFragment2; _fallbackChildFragment2.effectTag |= Placement; child = _primaryChildFragment2; _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the // fallback children. next = _fallbackChildFragment2; - child.return = next.return = workInProgress; } else { // Still haven't timed out. Continue rendering the children, like we // normally do. @@ -13181,7 +13960,9 @@ function retrySuspenseComponentWithoutHydrating( (function() { if (!(returnFiber !== null)) { throw ReactError( - "Suspense boundaries are never on the root. This is probably a bug in React." + Error( + "Suspense boundaries are never on the root. This is probably a bug in React." + ) ); } })(); @@ -13195,6 +13976,8 @@ function retrySuspenseComponentWithoutHydrating( current$$1.nextEffect = null; current$$1.effectTag = Deletion; + popSuspenseContext(workInProgress); + // Upgrade this work in progress to a real Suspense component. workInProgress.tag = SuspenseComponent; workInProgress.stateNode = null; @@ -13210,6 +13993,10 @@ function updateDehydratedSuspenseComponent( workInProgress, renderExpirationTime ) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); var suspenseInstance = workInProgress.stateNode; if (current$$1 === null) { // During the first pass, we'll bail out and not drill into the children. @@ -13302,6 +14089,382 @@ function updateDehydratedSuspenseComponent( } } +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderExpirationTime +) { + // 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; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + if (node.expirationTime < renderExpirationTime) { + node.expirationTime = renderExpirationTime; + } + var alternate = node.alternate; + if ( + alternate !== null && + alternate.expirationTime < renderExpirationTime + ) { + alternate.expirationTime = renderExpirationTime; + } + scheduleWorkOnParentPath(node.return, renderExpirationTime); + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) { + return; + } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} + +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; + } + row = row.sibling; + } + return lastContentRow; +} + +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + case "forward": + case "backward": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + default: + warning$1( + false, + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { + warning$1( + false, + "%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; + warning$1( + false, + '"%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; + warning$1( + false, + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); + } + } + } +} + +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + warning$1( + false, + "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; + } + } + 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 { + var iteratorFn = getIteratorFn(children); + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + _i++; + } + } + } else { + warning$1( + false, + '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 +) { + var renderState = workInProgress.memoizedState; + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailExpiration = 0; + 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. +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + 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$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + + var suspenseContext = suspenseStackCursor.current; + + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.effectTag |= DidCapture; + } else { + var didSuspendBefore = + current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; + 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, + renderExpirationTime + ); + } + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } + pushSuspenseContext(workInProgress, suspenseContext); + + if ((workInProgress.mode & BatchedMode) === NoMode) { + // Outside of batched 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 = void 0; + 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; + } + case "together": { + initSuspenseListRenderState( + workInProgress, + 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 workInProgress.child; +} + function updatePortalComponent( current$$1, workInProgress, @@ -13465,11 +14628,15 @@ function updateContextConsumer( return workInProgress.child; } -function updateEventComponent$1( +function updateFundamentalComponent$1( current$$1, workInProgress, renderExpirationTime ) { + var fundamentalImpl = workInProgress.type.impl; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; @@ -13479,38 +14646,6 @@ function updateEventComponent$1( nextChildren, renderExpirationTime ); - pushHostContextForEventComponent(workInProgress); - return workInProgress.child; -} - -function updateEventTarget(current$$1, workInProgress, renderExpirationTime) { - var type = workInProgress.type.type; - var nextProps = workInProgress.pendingProps; - var eventTargetChild = getEventTargetChildElement(type, nextProps); - - { - !(nextProps.children == null) - ? warning$1(false, "Event targets should not have children.") - : void 0; - } - if (eventTargetChild !== null) { - var child = (workInProgress.child = createFiberFromTypeAndProps( - eventTargetChild.type, - null, - eventTargetChild.props, - null, - workInProgress.mode, - renderExpirationTime - )); - child.return = workInProgress; - - if (current$$1 === null || current$$1.child === null) { - child.effectTag = Placement; - } - } else { - reconcileChildren(current$$1, workInProgress, null, renderExpirationTime); - } - pushHostContextForEventTarget(workInProgress); return workInProgress.child; } @@ -13526,8 +14661,8 @@ function bailoutOnAlreadyFinishedWork( cancelWorkTimer(workInProgress); if (current$$1 !== null) { - // Reuse previous context list - workInProgress.contextDependencies = current$$1.contextDependencies; + // Reuse previous dependencies + workInProgress.dependencies = current$$1.dependencies; } if (enableProfilerTimer) { @@ -13650,6 +14785,18 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { break; case HostComponent: pushHostContext(workInProgress); + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(workInProgress.type, newProps) + ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + // Schedule this fiber to re-render at offscreen priority. Then bailout. + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } break; case ClassComponent: { var Component = workInProgress.type; @@ -13696,6 +14843,10 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ); } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient // priority. Bailout. var child = bailoutOnAlreadyFinishedWork( @@ -13711,11 +14862,20 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { return null; } } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } break; } case DehydratedSuspenseComponent: { if (enableSuspenseServerRenderer) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has // been unsuspended it has committed as a regular Suspense component. // If it needs to be retried, it should have work scheduled on it. @@ -13723,15 +14883,46 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } break; } - case EventComponent: - if (enableEventAPI) { - pushHostContextForEventComponent(workInProgress); + case SuspenseListComponent: { + var didSuspendBefore = + (current$$1.effectTag & DidCapture) !== NoEffect; + + var childExpirationTime = workInProgress.childExpirationTime; + if (childExpirationTime < renderExpirationTime) { + // 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. + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (didSuspendBefore) { + workInProgress.effectTag |= DidCapture; + } + return null; } - break; - case EventTarget: { - if (enableEventAPI) { - pushHostContextForEventTarget(workInProgress); + + if (didSuspendBefore) { + // 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$$1, + workInProgress, + renderExpirationTime + ); + } + + // 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; } + pushSuspenseContext(workInProgress, suspenseStackCursor.current); break; } } @@ -13916,19 +15107,16 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } break; } - case EventComponent: { - if (enableEventAPI) { - return updateEventComponent$1( - current$$1, - workInProgress, - renderExpirationTime - ); - } - break; + case SuspenseListComponent: { + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } - case EventTarget: { - if (enableEventAPI) { - return updateEventTarget( + case FundamentalComponent: { + if (enableFundamentalAPI) { + return updateFundamentalComponent$1( current$$1, workInProgress, renderExpirationTime @@ -13940,12 +15128,28 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { (function() { { throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); } +function createFundamentalStateInstance(currentFiber, props, impl, state) { + return { + currentFiber: currentFiber, + impl: impl, + instance: null, + prevProps: null, + props: props, + state: state + }; +} + +var emptyObject$1 = {}; +var isArray$2 = Array.isArray; + function markUpdate(workInProgress) { // Tag the fiber with an update effect. This turns a Placement into // a PlacementAndUpdate. @@ -13975,6 +15179,8 @@ if (supportsMutation) { while (node !== null) { if (node.tag === HostComponent || node.tag === HostText) { appendInitialChild(parent, node.stateNode); + } else if (node.tag === FundamentalComponent) { + appendInitialChild(parent, node.stateNode.instance); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -14079,6 +15285,15 @@ if (supportsMutation) { _instance = cloneHiddenTextInstance(_instance, text, node); } appendInitialChild(parent, _instance); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance2 = node.stateNode.instance; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props = node.memoizedProps; + var _type = node.type; + _instance2 = cloneHiddenInstance(_instance2, _type, _props, node); + } + appendInitialChild(parent, _instance2); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -14157,13 +15372,22 @@ if (supportsMutation) { } appendChildToContainerChildSet(containerChildSet, instance); } else if (node.tag === HostText) { - var _instance2 = node.stateNode; + var _instance3 = node.stateNode; if (needsVisibilityToggle && isHidden) { // This child is inside a timed out tree. Hide it. var text = node.memoizedProps; - _instance2 = cloneHiddenTextInstance(_instance2, text, node); + _instance3 = cloneHiddenTextInstance(_instance3, text, node); } - appendChildToContainerChildSet(containerChildSet, _instance2); + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance4 = node.stateNode.instance; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props2 = node.memoizedProps; + var _type2 = node.type; + _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node); + } + appendChildToContainerChildSet(containerChildSet, _instance4); } else if (node.tag === HostPortal) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in @@ -14339,6 +15563,69 @@ if (supportsMutation) { }; } +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + tailNode = tailNode.sibling; + } + // Next we're simply going to delete all insertions after the + // last rendered item. + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } + break; + } + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } + _tailNode = _tailNode.sibling; + } + // Next we're simply going to delete all insertions after the + // last rendered item. + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + break; + } + } +} + function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; @@ -14389,6 +15676,20 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); + if (enableFlareAPI) { + var prevResponders = current.memoizedProps.responders; + var nextResponders = newProps.responders; + var instance = workInProgress.stateNode; + if (prevResponders !== nextResponders) { + updateEventResponders( + nextResponders, + instance, + rootContainerInstance, + workInProgress + ); + } + } + if (current.ref !== workInProgress.ref) { markRef$1(workInProgress); } @@ -14397,7 +15698,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { if (!(workInProgress.stateNode !== null)) { throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14426,7 +15729,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { markUpdate(workInProgress); } } else { - var instance = createInstance( + var _instance5 = createInstance( type, newProps, rootContainerInstance, @@ -14434,14 +15737,26 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress ); - appendAllChildren(instance, workInProgress, false, false); + appendAllChildren(_instance5, workInProgress, false, false); + + if (enableFlareAPI) { + var responders = newProps.responders; + if (responders != null) { + updateEventResponders( + responders, + _instance5, + rootContainerInstance, + workInProgress + ); + } + } // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. if ( finalizeInitialChildren( - instance, + _instance5, type, newProps, rootContainerInstance, @@ -14450,7 +15765,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { ) { markUpdate(workInProgress); } - workInProgress.stateNode = instance; + workInProgress.stateNode = _instance5; } if (workInProgress.ref !== null) { @@ -14472,7 +15787,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { if (!(workInProgress.stateNode !== null)) { throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14499,6 +15816,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { case ForwardRef: break; case SuspenseComponent: { + popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; if ((workInProgress.effectTag & DidCapture) !== NoEffect) { // Something suspended. Re-render with the fallback children. @@ -14519,15 +15837,8 @@ function completeWork(current, workInProgress, renderExpirationTime) { prevDidTimeout = prevState !== null; if (!nextDidTimeout && prevState !== null) { // We just switched from the fallback to the normal children. - - // Mark the event time of the switching from fallback to normal children, - // based on the start of when we first showed the fallback. This time - var fallbackExpirationTime = prevState.fallbackExpirationTime; - markRenderEventTime(fallbackExpirationTime); - // Delete the fallback. // TODO: Would it be better to store the fallback fragment on - // the stateNode during the begin phase? var currentFallbackChild = current.child.sibling; if (currentFallbackChild !== null) { // Deletions go at the beginning of the return fiber's effect list @@ -14545,13 +15856,37 @@ function completeWork(current, workInProgress, renderExpirationTime) { } if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in concurrent mode we can suspend, + // If this subtreee is running in batched 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 & ConcurrentMode) !== NoContext) { - renderDidSuspend(); + if ((workInProgress.mode & BatchedMode) !== 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(); + } } } @@ -14575,6 +15910,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress.effectTag |= Update; } } + if ( + enableSuspenseCallback && + workInProgress.updateQueue !== null && + workInProgress.memoizedProps.suspenseCallback != null + ) { + // Always notify the callback + workInProgress.effectTag |= Update; + } break; } case Fragment: @@ -14606,15 +15949,21 @@ function completeWork(current, workInProgress, renderExpirationTime) { } case DehydratedSuspenseComponent: { if (enableSuspenseServerRenderer) { + popSuspenseContext(workInProgress); if (current === null) { var _wasHydrated2 = popHydrationState(workInProgress); (function() { if (!_wasHydrated2) { throw ReactError( - "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ) ); } })(); + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } skipPastDehydratedSuspenseInstance(workInProgress); } else if ((workInProgress.effectTag & DidCapture) === NoEffect) { // This boundary did not suspend so it's now hydrated. @@ -14629,55 +15978,239 @@ function completeWork(current, workInProgress, renderExpirationTime) { } break; } - case EventComponent: { - if (enableEventAPI) { - popHostContext(workInProgress); - var _rootContainerInstance2 = getRootHostContainer(); - var responder = workInProgress.type.responder; - var eventComponentInstance = workInProgress.stateNode; - - if (eventComponentInstance === null) { - var responderState = null; - if (responder.createInitialState !== undefined) { - responderState = responder.createInitialState(newProps); + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. We don't do anything + // in this mode. + break; + } + + var didSuspendAlready = + (workInProgress.effectTag & DidCapture) !== NoEffect; + + var renderedTail = renderState.rendering; + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.effectTag & DidCapture) === NoEffect); + if (!cannotBeSuspended) { + var row = workInProgress.child; + while (row !== null) { + var suspended = findFirstSuspended(row); + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.effectTag |= 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. + var newThennables = suspended.updateQueue; + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.effectTag |= 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. + workInProgress.firstEffect = workInProgress.lastEffect = null; + // Reset the child fibers to their original state. + resetChildFibers(workInProgress, renderExpirationTime); + + // Set up the Suspense Context to force suspense and immediately + // rerender the children. + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } + row = row.sibling; + } } - eventComponentInstance = workInProgress.stateNode = { - currentFiber: workInProgress, - props: newProps, - responder: responder, - rootEventTypes: null, - rootInstance: _rootContainerInstance2, - state: responderState - }; - markUpdate(workInProgress); } else { - // Update the props on the event component state node - eventComponentInstance.props = newProps; - // Update the root container, so we can properly unmount events at some point - eventComponentInstance.rootInstance = _rootContainerInstance2; - // Update the current fiber - eventComponentInstance.currentFiber = workInProgress; - updateEventComponent(eventComponentInstance); + cutOffTailIfNeeded(renderState, false); + } + // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + if (_suspended !== null) { + workInProgress.effectTag |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, true); + // This might have been modified. + if ( + renderState.tail === null && + renderState.tailMode === "hidden" + ) { + // We need to delete the row we just rendered. + // Ensure we transfer the update queue to the parent. + var _newThennables = _suspended.updateQueue; + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.effectTag |= Update; + } + // Reset the effect list to what it w as 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. + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } + // We're done. + return null; + } + } else if ( + now() > renderState.tailExpiration && + renderExpirationTime > Never + ) { + // 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.effectTag |= 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. If we can show + // them, then they really have the same priority as this render. + // So we'll pick it back up the very next render pass once we've had + // an opportunity to yield for paint. + + var nextPriority = renderExpirationTime - 1; + workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; + if (enableSchedulerTracing) { + markSpawnedWork(nextPriority); + } + } + } + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } + renderState.last = renderedTail; + } + } + + if (renderState.tail !== null) { + // We still have tail rows to render. + if (renderState.tailExpiration === 0) { + // Heuristic for how long we're willing to spend rendering rows + // until we just give up and show what we have so far. + var TAIL_EXPIRATION_TIMEOUT_MS = 500; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + } + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.lastEffect = workInProgress.lastEffect; + next.sibling = null; + + // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + var suspenseContext = suspenseStackCursor.current; + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } + pushSuspenseContext(workInProgress, suspenseContext); + // Do a pass over the next row. + return next; } break; } - case EventTarget: { - if (enableEventAPI) { - popHostContext(workInProgress); - var _type = workInProgress.type.type; - var _rootContainerInstance3 = getRootHostContainer(); - var shouldUpdate = handleEventTarget( - _type, - newProps, - _rootContainerInstance3, - workInProgress - ); - // Update the latest props on the stateNode. This is used - // during the event phase to find the most current props. - workInProgress.stateNode.props = newProps; - if (shouldUpdate) { - markUpdate(workInProgress); + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalImpl = workInProgress.type.impl; + var fundamentalInstance = workInProgress.stateNode; + + if (fundamentalInstance === null) { + var getInitialState = fundamentalImpl.getInitialState; + var fundamentalState = void 0; + if (getInitialState !== undefined) { + fundamentalState = getInitialState(newProps); + } + fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance( + workInProgress, + newProps, + fundamentalImpl, + fundamentalState || {} + ); + var _instance6 = getFundamentalComponentInstance(fundamentalInstance); + fundamentalInstance.instance = _instance6; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } + appendAllChildren(_instance6, workInProgress, false, false); + mountFundamentalComponent(fundamentalInstance); + } else { + // We fire update in commit phase + var prevProps = fundamentalInstance.props; + fundamentalInstance.prevProps = prevProps; + fundamentalInstance.props = newProps; + fundamentalInstance.currentFiber = workInProgress; + if (supportsPersistence) { + var _instance7 = cloneFundamentalInstance(fundamentalInstance); + fundamentalInstance.instance = _instance7; + appendAllChildren(_instance7, workInProgress, false, false); + } + var shouldUpdate = shouldUpdateFundamentalComponent( + fundamentalInstance + ); + if (shouldUpdate) { + markUpdate(workInProgress); + } } } break; @@ -14686,7 +16219,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (function() { { throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -14695,15 +16230,263 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } -function shouldCaptureSuspense(workInProgress) { - // In order to capture, the Suspense component must have a fallback prop. - if (workInProgress.memoizedProps.fallback === undefined) { - return false; +function mountEventResponder( + responder, + responderProps, + instance, + rootContainerInstance, + fiber, + respondersMap +) { + var responderState = emptyObject$1; + var getInitialState = responder.getInitialState; + if (getInitialState !== null) { + responderState = getInitialState(responderProps); + } + var responderInstance = createResponderInstance( + responder, + responderProps, + responderState, + instance, + fiber + ); + mountResponderInstance( + responder, + responderInstance, + responderProps, + responderState, + instance, + rootContainerInstance + ); + respondersMap.set(responder, responderInstance); +} + +function updateEventResponder( + responder, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance +) { + (function() { + if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) { + throw ReactError( + Error( + "An invalid value was used as an event responder. Expect one or many event responders created via React.unstable_createResponer()." + ) + ); + } + })(); + if (visistedResponders.has(responder)) { + // show warning + return; + } + visistedResponders.add(responder); + var responderInstance = respondersMap.get(responder); + + if (responderInstance === undefined) { + // Mount + mountEventResponder( + responder, + props, + instance, + rootContainerInstance, + fiber, + respondersMap + ); + } else { + // Update + responderInstance.props = props; + responderInstance.fiber = fiber; + } +} + +function updateEventResponders( + responders, + instance, + rootContainerInstance, + fiber +) { + var visistedResponders = new Set(); + var dependencies = fiber.dependencies; + if (responders != null) { + if (dependencies === null) { + dependencies = fiber.dependencies = { + expirationTime: NoWork, + firstContext: null, + listeners: null, + responders: new Map() + }; + } + var respondersMap = dependencies.responders; + if (respondersMap === null) { + respondersMap = new Map(); + } + if (isArray$2(responders)) { + for (var i = 0, length = responders.length; i < length; i++) { + var _responders$i = responders[i], + type = _responders$i.type, + props = _responders$i.props; + + updateEventResponder( + type, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance + ); + } + } else { + var type = responders.type, + props = responders.props; + + updateEventResponder( + type, + props, + fiber, + visistedResponders, + respondersMap, + instance, + rootContainerInstance + ); + } + } + if (dependencies !== null) { + var _respondersMap = dependencies.responders; + if (_respondersMap !== null) { + // Unmount + var mountedResponders = Array.from(_respondersMap.keys()); + for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { + var mountedResponder = mountedResponders[_i]; + if (!visistedResponders.has(mountedResponder)) { + var responderInstance = _respondersMap.get(mountedResponder); + unmountResponderInstance(responderInstance); + _respondersMap.delete(mountedResponder); + } + } + } + } +} + +function unwindWork(workInProgress, renderExpirationTime) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; + if (isContextProvider(Component)) { + popContext(workInProgress); + } + var effectTag = workInProgress.effectTag; + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + return null; + } + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; + (function() { + if (!((_effectTag & DidCapture) === NoEffect)) { + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + } + })(); + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var _effectTag2 = workInProgress.effectTag; + if (_effectTag2 & ShouldCapture) { + workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; + // Captured a suspense effect. Re-render the boundary. + return workInProgress; + } + return null; + } + case DehydratedSuspenseComponent: { + if (enableSuspenseServerRenderer) { + // TODO: popHydrationState + popSuspenseContext(workInProgress); + var _effectTag3 = workInProgress.effectTag; + if (_effectTag3 & ShouldCapture) { + workInProgress.effectTag = + (_effectTag3 & ~ShouldCapture) | DidCapture; + // Captured a suspense effect. Re-render the boundary. + return workInProgress; + } + } + 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. + return null; + } + case HostPortal: + popHostContainer(workInProgress); + return null; + case ContextProvider: + popProvider(workInProgress); + return null; + default: + return null; + } +} + +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } + break; + } + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + break; + } + case HostComponent: { + popHostContext(interruptedWork); + break; + } + case HostPortal: + popHostContainer(interruptedWork); + break; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; + case DehydratedSuspenseComponent: + if (enableSuspenseServerRenderer) { + // TODO: popHydrationState + popSuspenseContext(interruptedWork); + } + break; + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; + case ContextProvider: + popProvider(interruptedWork); + break; + default: + break; } - // If it was the primary children that just suspended, capture and render the - // fallback. Otherwise, don't capture and bubble to the next boundary. - var nextState = workInProgress.memoizedState; - return nextState === null; } function createCapturedValue(value, source) { @@ -14717,47 +16500,23 @@ function createCapturedValue(value, source) { } // Module provided by RN: -/** - * Intercept lifecycle errors and ensure they are shown with the correct stack - * trace within the native redbox component. - */ -function showErrorDialog(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - - var errorToHandle = void 0; - - // Typically Errors are thrown but eg strings or null can be thrown as well. - if (error instanceof Error) { - var message = error.message, - name = error.name; - - var summary = message ? name + ": " + message : name; - - errorToHandle = error; - - try { - errorToHandle.message = - summary + "\n\nThis error is located at:" + componentStack; - } catch (e) {} - } else if (typeof error === "string") { - errorToHandle = new Error( - error + "\n\nThis error is located at:" + componentStack +(function() { + if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog + .showErrorDialog === "function" + ) + ) { + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") ); - } else { - errorToHandle = new Error("Unspecified error at:" + componentStack); } +})(); - ReactNativePrivateInterface.ExceptionsManager.handleException( - errorToHandle, - false +function showErrorDialog(capturedError) { + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError ); - - // Return false here to prevent ReactFiberErrorLogger default behavior of - // logging error details to console.error. Calls to console.error are - // automatically routed to the native redbox controller, which we've already - // done above by calling ExceptionsManager. - return false; } function logCapturedError(capturedError) { @@ -15007,14 +16766,15 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case HostText: case HostPortal: case IncompleteClassComponent: - case EventTarget: // Nothing to do for these component types return; default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15083,8 +16843,19 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } function commitPassiveHookEffects(finishedWork) { - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if ((finishedWork.effectTag & Passive) !== NoEffect) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + break; + } + default: + break; + } + } } function commitLifeCycles( @@ -15281,73 +17052,43 @@ function commitLifeCycles( if (enableProfilerTimer) { var onRender = finishedWork.memoizedProps.onRender; - if (enableSchedulerTracing) { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime(), - finishedRoot.memoizedInteractions - ); - } else { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime() - ); + if (typeof onRender === "function") { + if (enableSchedulerTracing) { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime(), + finishedRoot.memoizedInteractions + ); + } else { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime() + ); + } } } return; } case SuspenseComponent: + case SuspenseListComponent: case IncompleteClassComponent: + case FundamentalComponent: return; - case EventTarget: { - if (enableEventAPI) { - var _type = finishedWork.type.type; - var _props = finishedWork.memoizedProps; - var _instance3 = finishedWork.stateNode; - var parentInstance = null; - - var node = finishedWork.return; - // Traverse up the fiber tree until we find the parent host node. - while (node !== null) { - if (node.tag === HostComponent) { - parentInstance = node.stateNode; - break; - } else if (node.tag === HostRoot) { - parentInstance = node.stateNode.containerInfo; - break; - } - node = node.return; - } - (function() { - if (!(parentInstance !== null)) { - throw ReactError( - "This should have a parent host component initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } - })(); - commitEventTarget(_type, _props, _instance3, parentInstance); - } - return; - } - case EventComponent: { - if (enableEventAPI) { - mountEventComponent(finishedWork.stateNode); - } - return; - } default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15368,11 +17109,11 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { unhideInstance(node.stateNode, node.memoizedProps); } } else if (node.tag === HostText) { - var _instance4 = node.stateNode; + var _instance3 = node.stateNode; if (isHidden) { - hideTextInstance(_instance4); + hideTextInstance(_instance3); } else { - unhideTextInstance(_instance4, node.memoizedProps); + unhideTextInstance(_instance3, node.memoizedProps); } } else if ( node.tag === SuspenseComponent && @@ -15483,6 +17224,25 @@ function commitUnmount(current$$1) { return; } case HostComponent: { + if (enableFlareAPI) { + var dependencies = current$$1.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + for ( + var i = 0, length = responderInstances.length; + i < length; + i++ + ) { + var responderInstance = responderInstances[i]; + unmountResponderInstance(responderInstance); + } + dependencies.responders = null; + } + } + } safelyDetachRef(current$$1); return; } @@ -15497,11 +17257,13 @@ function commitUnmount(current$$1) { } return; } - case EventComponent: { - if (enableEventAPI) { - var eventComponentInstance = current$$1.stateNode; - unmountEventComponent(eventComponentInstance); - current$$1.stateNode = null; + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = current$$1.stateNode; + if (fundamentalInstance !== null) { + unmountFundamentalComponent(fundamentalInstance); + current$$1.stateNode = null; + } } } } @@ -15551,12 +17313,14 @@ function detachFiber(current$$1) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; if (alternate !== null) { alternate.return = null; alternate.child = null; alternate.memoizedState = null; alternate.updateQueue = null; + alternate.dependencies = null; } } @@ -15581,8 +17345,7 @@ function commitContainer(finishedWork) { case ClassComponent: case HostComponent: case HostText: - case EventTarget: - case EventComponent: { + case FundamentalComponent: { return; } case HostRoot: @@ -15598,7 +17361,9 @@ function commitContainer(finishedWork) { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15617,7 +17382,9 @@ function getHostParentFiber(fiber) { (function() { { throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15687,25 +17454,33 @@ function commitPlacement(finishedWork) { // Note: these two variables *must* always be updated together. var parent = void 0; var isContainer = void 0; - + var parentStateNode = parentFiber.stateNode; switch (parentFiber.tag) { case HostComponent: - parent = parentFiber.stateNode; + parent = parentStateNode; isContainer = false; break; case HostRoot: - parent = parentFiber.stateNode.containerInfo; + parent = parentStateNode.containerInfo; isContainer = true; break; case HostPortal: - parent = parentFiber.stateNode.containerInfo; + parent = parentStateNode.containerInfo; isContainer = true; break; + case FundamentalComponent: + if (enableFundamentalAPI) { + parent = parentStateNode.instance; + isContainer = false; + } + // eslint-disable-next-line-no-fallthrough default: (function() { { throw ReactError( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15720,8 +17495,9 @@ function commitPlacement(finishedWork) { // children to find all the terminal nodes. var node = finishedWork; while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - var stateNode = node.stateNode; + var isHost = node.tag === HostComponent || node.tag === HostText; + if (isHost || node.tag === FundamentalComponent) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; if (before) { if (isContainer) { insertInContainerBefore(parent, stateNode, before); @@ -15777,23 +17553,31 @@ function unmountHostComponents(current$$1) { (function() { if (!(parent !== null)) { throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); + var parentStateNode = parent.stateNode; switch (parent.tag) { case HostComponent: - currentParent = parent.stateNode; + currentParent = parentStateNode; currentParentIsContainer = false; break findParent; case HostRoot: - currentParent = parent.stateNode.containerInfo; + currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; case HostPortal: - currentParent = parent.stateNode.containerInfo; + currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; + case FundamentalComponent: + if (enableFundamentalAPI) { + currentParent = parentStateNode.instance; + currentParentIsContainer = false; + } } parent = parent.return; } @@ -15810,6 +17594,16 @@ function unmountHostComponents(current$$1) { removeChild(currentParent, node.stateNode); } // Don't visit children because we already visited them. + } else if (node.tag === FundamentalComponent) { + var fundamentalNode = node.stateNode.instance; + commitNestedUnmounts(node); + // After all the children have unmounted, it is now safe to remove the + // node from the tree. + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, fundamentalNode); + } else { + removeChild(currentParent, fundamentalNode); + } } else if ( enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent @@ -15888,6 +17682,11 @@ function commitWork(current$$1, finishedWork) { } case SuspenseComponent: { commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } } @@ -15940,7 +17739,9 @@ function commitWork(current$$1, finishedWork) { (function() { if (!(finishedWork.stateNode !== null)) { throw ReactError( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ) ); } })(); @@ -15953,9 +17754,6 @@ function commitWork(current$$1, finishedWork) { commitTextUpdate(textInstance, oldText, newText); return; } - case EventTarget: { - return; - } case HostRoot: { return; } @@ -15964,19 +17762,30 @@ function commitWork(current$$1, finishedWork) { } case SuspenseComponent: { commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } case IncompleteClassComponent: { return; } - case EventComponent: { + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = finishedWork.stateNode; + updateFundamentalComponent(fundamentalInstance); + } return; } default: { (function() { { throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } })(); @@ -15994,25 +17803,31 @@ function commitSuspenseComponent(finishedWork) { } else { newDidTimeout = true; primaryChildParent = finishedWork.child; - if (newState.fallbackExpirationTime === NoWork) { - // If the children had not already timed out, record the time. - // This is used to compute the elapsed time during subsequent - // attempts to render the children. - // We model this as a normal pri expiration time since that's - // how we infer start time for updates. - newState.fallbackExpirationTime = computeAsyncExpirationNoBucket( - requestCurrentTime() - ); - } + markCommitTimeOfFallback(); } if (supportsMutation && primaryChildParent !== null) { hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); } + if (enableSuspenseCallback && newState !== null) { + var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; + if (typeof suspenseCallback === "function") { + var thenables = finishedWork.updateQueue; + if (thenables !== null) { + suspenseCallback(new Set(thenables)); + } + } else { + if (suspenseCallback !== undefined) { + warning$1(false, "Unexpected type for suspenseCallback."); + } + } + } +} + +function attachSuspenseRetryListeners(finishedWork) { // If this boundary just timed out, then it will have a set of thenables. // For each thenable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. var thenables = finishedWork.updateQueue; if (thenables !== null) { finishedWork.updateQueue = null; @@ -16045,7 +17860,7 @@ var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, null); // Unmount the root by rendering null. update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property @@ -16060,7 +17875,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, null); update.tag = CaptureUpdate; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { @@ -16084,6 +17899,8 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // TODO: Warn in strict mode if getDerivedStateFromError is // not defined. markLegacyErrorBoundaryAsFailed(this); + + // Only log here if componentDidCatch is the only error boundary method defined logError(fiber, errorInfo); } var error = errorInfo.value; @@ -16168,12 +17985,19 @@ function throwException( // This is a thenable. var thenable = value; + checkForWrongSuspensePriorityInDEV(sourceFiber); + + 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) + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) ) { // Found the nearest boundary. @@ -16187,15 +18011,15 @@ function throwException( thenables.add(thenable); } - // If the boundary is outside of concurrent mode, we should *not* + // If the boundary is outside of batched 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 concurrent mode tree. If the Suspense is outside of it, we + // inside a batched mode tree. If the Suspense is outside of it, we // should *not* suspend the commit. - if ((_workInProgress.mode & ConcurrentMode) === NoContext) { + if ((_workInProgress.mode & BatchedMode) === NoMode) { _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete. @@ -16212,9 +18036,9 @@ function throwException( 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 updte to + // since it's known to be in an inconsistent state. Use a force update to // prevent a bail out. - var update = createUpdate(Sync); + var update = createUpdate(Sync, null); update.tag = ForceUpdate; enqueueUpdate(sourceFiber, update); } @@ -16230,11 +18054,51 @@ function throwException( // 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. SuspenseConfig applies 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. attachPingListener(root, renderExpirationTime, thenable); _workInProgress.effectTag |= ShouldCapture; _workInProgress.expirationTime = renderExpirationTime; + return; } else if ( enableSuspenseServerRenderer && @@ -16250,7 +18114,9 @@ function throwException( (function() { if (!current$$1) { throw ReactError( - "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React." + Error( + "A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React." + ) ); } })(); @@ -16340,130 +18206,29 @@ function throwException( } while (workInProgress !== null); } -function unwindWork(workInProgress, renderExpirationTime) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; - if (isContextProvider(Component)) { - popContext(workInProgress); - } - var effectTag = workInProgress.effectTag; - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - return null; - } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; - (function() { - if (!((_effectTag & DidCapture) === NoEffect)) { - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - })(); - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; - } - case SuspenseComponent: { - var _effectTag2 = workInProgress.effectTag; - if (_effectTag2 & ShouldCapture) { - workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; - // Captured a suspense effect. Re-render the boundary. - return workInProgress; - } - return null; - } - case DehydratedSuspenseComponent: { - if (enableSuspenseServerRenderer) { - // TODO: popHydrationState - var _effectTag3 = workInProgress.effectTag; - if (_effectTag3 & ShouldCapture) { - workInProgress.effectTag = - (_effectTag3 & ~ShouldCapture) | DidCapture; - // Captured a suspense effect. Re-render the boundary. - return workInProgress; - } - } - return null; - } - case HostPortal: - popHostContainer(workInProgress); - return null; - case ContextProvider: - popProvider(workInProgress); - return null; - case EventComponent: - case EventTarget: - if (enableEventAPI) { - popHostContext(workInProgress); - } - return null; - default: - return null; - } -} - -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); - } - break; - } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - break; - } - case HostComponent: { - popHostContext(interruptedWork); - break; - } - case HostPortal: - popHostContainer(interruptedWork); - break; - case ContextProvider: - popProvider(interruptedWork); - break; - default: - break; - } -} - -// TODO: Ahaha Andrew is bad at spellling // DEV stuff var ceil = Math.ceil; var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; -var ReactShouldWarnActingUpdates = - ReactSharedInternals.ReactShouldWarnActingUpdates; +var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; -var NotWorking = 0; -var BatchedPhase = 1; -var LegacyUnbatchedPhase = 2; -var FlushSyncPhase = 3; -var RenderPhase = 4; -var CommitPhase = 5; +var NoContext = /* */ 0; +var BatchedContext = /* */ 1; +var EventContext = /* */ 2; +var DiscreteEventContext = /* */ 4; +var LegacyUnbatchedContext = /* */ 8; +var RenderContext = /* */ 16; +var CommitContext = /* */ 32; var RootIncomplete = 0; var RootErrored = 1; var RootSuspended = 2; -var RootCompleted = 3; +var RootSuspendedWithDelay = 3; +var RootCompleted = 4; -// The phase of work we're currently in -var workPhase = NotWorking; +// Describes where we are in the React execution stack +var executionContext = NoContext; // The root we're working on var workInProgressRoot = null; // The fiber we're working on @@ -16476,7 +18241,17 @@ var workInProgressRootExitStatus = RootIncomplete; // This is conceptually a time stamp but expressed in terms of an ExpirationTime // because we deal mostly with expiration times in the hot path, so this avoids // the conversion happening in the hot path. -var workInProgressRootMostRecentEventTime = Sync; +var workInProgressRootLatestProcessedExpirationTime = Sync; +var workInProgressRootLatestSuspenseTimeout = Sync; +var workInProgressRootCanSuspendUsingConfig = null; +// If we're pinged while rendering we don't always restart immediately. +// This flag determines if it might be worthwhile to restart if an opportunity +// happens latere. +var workInProgressRootHasPendingPing = false; +// 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; +var FALLBACK_THROTTLE_MS = 500; var nextEffect = null; var hasUncaughtError = false; @@ -16499,6 +18274,12 @@ var nestedPassiveUpdateCount = 0; var interruptedBy = null; +// Marks the need to reschedule pending interactions at these expiration times +// during the commit phase. This enables them to be traced across components +// that spawn new work during render. E.g. hidden boundaries, suspended SSR +// hydration or SuspenseList. +var spawnedWorkDuringRender = null; + // Expiration times are computed by adding to the current time (the start // time). However, if two updates are scheduled within the same event, we // should treat their start times as simultaneous, even if the actual clock @@ -16510,7 +18291,7 @@ var interruptedBy = null; var currentEventTime = NoWork; function requestCurrentTime() { - if (workPhase === RenderPhase || workPhase === CommitPhase) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { // We're inside React, so it's fine to read the actual time. return msToExpirationTime(now()); } @@ -16524,46 +18305,62 @@ function requestCurrentTime() { return currentEventTime; } -function computeExpirationForFiber(currentTime, fiber) { - if ((fiber.mode & ConcurrentMode) === NoContext) { +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + var mode = fiber.mode; + if ((mode & BatchedMode) === NoMode) { return Sync; } - if (workPhase === RenderPhase) { + var priorityLevel = getCurrentPriorityLevel(); + if ((mode & ConcurrentMode) === NoMode) { + return priorityLevel === ImmediatePriority ? Sync : Batched; + } + + if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering return renderExpirationTime; } - // Compute an expiration time based on the Scheduler priority. var expirationTime = void 0; - var priorityLevel = getCurrentPriorityLevel(); - switch (priorityLevel) { - case ImmediatePriority: - expirationTime = Sync; - break; - case UserBlockingPriority: - // TODO: Rename this to computeUserBlockingExpiration - expirationTime = computeInteractiveExpiration(currentTime); - break; - case NormalPriority: - case LowPriority: - // TODO: Handle LowPriority - // TODO: Rename this to... something better. - expirationTime = computeAsyncExpiration(currentTime); - break; - case IdlePriority: - expirationTime = Never; - break; - default: - (function() { - { - throw ReactError("Expected a valid priority level"); - } - })(); + if (suspenseConfig !== null) { + // Compute an expiration time based on the Suspense timeout. + expirationTime = computeSuspenseExpiration( + currentTime, + suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION + ); + } else { + // Compute an expiration time based on the Scheduler priority. + switch (priorityLevel) { + case ImmediatePriority: + expirationTime = Sync; + break; + case UserBlockingPriority: + // TODO: Rename this to computeUserBlockingExpiration + expirationTime = computeInteractiveExpiration(currentTime); + break; + case NormalPriority: + case LowPriority: + // TODO: Handle LowPriority + // TODO: Rename this to... something better. + expirationTime = computeAsyncExpiration(currentTime); + break; + case IdlePriority: + expirationTime = Never; + break; + default: + (function() { + { + throw ReactError(Error("Expected a valid priority level")); + } + })(); + } } // If we're in the middle of rendering a tree, do not update at the same // expiration time that is already rendering. + // TODO: We shouldn't have to do this if the update is on a different root. + // Refactor computeExpirationForFiber + scheduleUpdate so we have access to + // the root when we check for this condition. if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; @@ -16587,8 +18384,20 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { checkForInterruption(fiber, expirationTime); recordScheduleUpdate(); + // TODO: computeExpirationForFiber also reads the priority. Pass the + // priority as an argument to that function and this one. + var priorityLevel = getCurrentPriorityLevel(); + if (expirationTime === Sync) { - if (workPhase === LegacyUnbatchedPhase) { + if ( + // Check if we're inside unbatchedUpdates + (executionContext & LegacyUnbatchedContext) !== NoContext && + // Check if we're not already rendering + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + // Register pending interactions on the root to avoid losing traced interaction data. + schedulePendingInteractions(root, expirationTime); + // This is a legacy edge case. The initial mount of a ReactDOM.render-ed // root inside of batchedUpdates should be synchronous, but layout updates // should be deferred until the end of the batch. @@ -16598,35 +18407,36 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { } } else { scheduleCallbackForRoot(root, ImmediatePriority, Sync); - if (workPhase === NotWorking) { + if (executionContext === NoContext) { // Flush the synchronous work now, wnless we're already working or inside // a batch. This is intentionally inside scheduleUpdateOnFiber instead of // scheduleCallbackForFiber to preserve the ability to schedule a callback - // without immediately flushing it. We only do this for user-initated + // without immediately flushing it. We only do this for user-initiated // updates, to preserve historical behavior of sync mode. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } } else { - // TODO: computeExpirationForFiber also reads the priority. Pass the - // priority as an argument to that function and this one. - var priorityLevel = getCurrentPriorityLevel(); - if (priorityLevel === UserBlockingPriority) { - // This is the result of a discrete event. Track the lowest priority - // discrete update per root so we can flush them early, if needed. - if (rootsWithPendingDiscreteUpdates === null) { - rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); - } else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); - if ( - lastDiscreteTime === undefined || - lastDiscreteTime > expirationTime - ) { - rootsWithPendingDiscreteUpdates.set(root, expirationTime); - } + scheduleCallbackForRoot(root, priorityLevel, expirationTime); + } + + if ( + (executionContext & DiscreteEventContext) !== NoContext && + // Only updates at user-blocking priority or greater are considered + // discrete, even inside a discrete event. + (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. + if (rootsWithPendingDiscreteUpdates === null) { + rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); + } else { + var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); + if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) { + rootsWithPendingDiscreteUpdates.set(root, expirationTime); } } - scheduleCallbackForRoot(root, priorityLevel, expirationTime); } } var scheduleWork = scheduleUpdateOnFiber; @@ -16707,42 +18517,46 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { } root.callbackExpirationTime = expirationTime; - var options = null; - if (expirationTime !== Sync && expirationTime !== Never) { - var timeout = expirationTimeToMs(expirationTime) - now(); - if (timeout > 5000) { - // Sanity check. Should never take longer than 5 seconds. - // TODO: Add internal warning? - timeout = 5000; + if (expirationTime === Sync) { + // Sync React callbacks are scheduled on a special internal queue + root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + ); + } else { + var options = null; + if (expirationTime !== Never) { + var timeout = expirationTimeToMs(expirationTime) - now(); + options = { timeout: timeout }; + } + + root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + options + ); + if ( + enableUserTimingAPI && + expirationTime !== Sync && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + // Scheduled an async callback, and we're not already working. Add an + // entry to the flamegraph that shows we're waiting for a callback + // to fire. + startRequestCallbackTimer(); } - options = { timeout: timeout }; - } - - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - options - ); - if ( - enableUserTimingAPI && - expirationTime !== Sync && - workPhase !== RenderPhase && - workPhase !== CommitPhase - ) { - // Scheduled an async callback, and we're not already working. Add an - // entry to the flamegraph that shows we're waiting for a callback - // to fire. - startRequestCallbackTimer(); } } - // Add the current set of interactions to the pending set associated with - // this root. - schedulePendingInteraction(root, expirationTime); + // Associate the current interactions with this new root+priority. + schedulePendingInteractions(root, expirationTime); } function runRootCallback(root, callback, isSync) { @@ -16767,15 +18581,33 @@ function runRootCallback(root, callback, isSync) { } } -function flushInteractiveUpdates$1() { - if (workPhase === RenderPhase || workPhase === CommitPhase) { - // Can't synchronously flush interactive updates if React is already - // working. This is currently a no-op. - // TODO: Should we fire a warning? This happens if you synchronously invoke - // an input event inside an effect, like with `element.click()`. +function flushDiscreteUpdates() { + // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. + // However, `act` uses `batchedUpdates`, so there's no way to distinguish + // those two cases. Need to fix this before exposing flushDiscreteUpdates + // as a public API. + if ( + (executionContext & (BatchedContext | RenderContext | CommitContext)) !== + NoContext + ) { + if (true && (executionContext & RenderContext) !== NoContext) { + warning$1( + false, + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } + // We're already rendering, so we can't synchronously flush pending work. + // This is probably a nested event dispatch triggered by a lifecycle/effect, + // like `el.focus()`. Exit. return; } flushPendingDiscreteUpdates(); + if (!revertPassiveEffectsChange) { + // If the discrete updates scheduled passive effects, flush them now so that + // they fire before the next serial event. + flushPassiveEffects(); + } } function resolveLocksOnRoot(root, expirationTime) { @@ -16785,8 +18617,6 @@ function resolveLocksOnRoot(root, expirationTime) { firstBatch._defer && firstBatch._expirationTime >= expirationTime ) { - root.finishedWork = root.current.alternate; - root.pendingCommitExpirationTime = expirationTime; scheduleCallback(NormalPriority, function() { firstBatch._onComplete(); return null; @@ -16797,15 +18627,6 @@ function resolveLocksOnRoot(root, expirationTime) { } } -function interactiveUpdates$1(fn, a, b, c) { - if (workPhase === NotWorking) { - // TODO: Remove this call. Instead of doing this automatically, the caller - // should explicitly call flushInteractiveUpdates. - flushPendingDiscreteUpdates(); - } - return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); -} - function flushPendingDiscreteUpdates() { if (rootsWithPendingDiscreteUpdates !== null) { // For each root with pending discrete updates, schedule a callback to @@ -16813,56 +18634,84 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback( - ImmediatePriority, - renderRoot.bind(null, root, expirationTime) - ); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); // Now flush the immediate queue. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function batchedUpdates$1(fn, a) { - if (workPhase !== NotWorking) { - // We're already working, or inside a batch, so batchedUpdates is a no-op. + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + try { return fn(a); + } finally { + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } } - workPhase = BatchedPhase; +} + +function batchedEventUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= EventContext; try { return fn(a); } finally { - workPhase = NotWorking; - // Flush the immediate callbacks that were scheduled during this batch - flushImmediateQueue(); + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} + +function discreteUpdates$1(fn, a, b, c) { + var prevExecutionContext = executionContext; + executionContext |= DiscreteEventContext; + try { + // Should this + return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); + } finally { + executionContext = prevExecutionContext; + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } } } function flushSync(fn, a) { - if (workPhase === RenderPhase || workPhase === CommitPhase) { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { (function() { { throw ReactError( - "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." + Error( + "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." + ) ); } })(); } - var prevWorkPhase = workPhase; - workPhase = FlushSyncPhase; + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; try { return runWithPriority(ImmediatePriority, fn.bind(null, a)); } finally { - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up // the stack. - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = NoWork; + root.finishedWork = null; + root.finishedExpirationTime = NoWork; var timeoutHandle = root.timeoutHandle; if (timeoutHandle !== noTimeout) { @@ -16884,17 +18733,26 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = Sync; + workInProgressRootLatestProcessedExpirationTime = Sync; + workInProgressRootLatestSuspenseTimeout = Sync; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = false; + + if (enableSchedulerTracing) { + spawnedWorkDuringRender = null; + } { ReactStrictModeWarnings.discardPendingWarnings(); + componentsThatSuspendedAtHighPri = null; + componentsThatTriggeredHighPriSuspend = null; } } function renderRoot(root, expirationTime, isSync) { (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Should not already be working."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError(Error("Should not already be working.")); } })(); @@ -16910,10 +18768,11 @@ function renderRoot(root, expirationTime, isSync) { return null; } - if (root.pendingCommitExpirationTime === expirationTime) { + if (isSync && root.finishedExpirationTime === expirationTime) { // There's already a pending commit at this expiration time. - root.pendingCommitExpirationTime = NoWork; - return commitRoot.bind(null, root, expirationTime); + // TODO: This is poorly factored. This case only exists for the + // batch.commit() API. + return commitRoot.bind(null, root); } flushPassiveEffects(); @@ -16922,14 +18781,34 @@ function renderRoot(root, expirationTime, isSync) { // and prepare a fresh one. Otherwise we'll continue where we left off. if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) { prepareFreshStack(root, expirationTime); - startWorkOnPendingInteraction(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) { + // We could've received an update at a lower priority while we yielded. + // We're suspended in a delayed state. Once we complete this render we're + // just going to try to recover at the last pending time anyway so we might + // as well start doing that eagerly. + // Ideally we should be able to do this even for retries but we don't yet + // know if we're going to process an update which wants to commit earlier, + // and this path happens very early so it would happen too often. Instead, + // for that case, we'll wait until we complete. + if (workInProgressRootHasPendingPing) { + // We have a ping at this expiration. Let's restart to see if we get unblocked. + prepareFreshStack(root, expirationTime); + } else { + var lastPendingTime = root.lastPendingTime; + if (lastPendingTime < expirationTime) { + // There's lower priority work. It might be unsuspended. Try rendering + // at that level immediately, while preserving the position in the queue. + return renderRoot.bind(null, root, lastPendingTime); + } + } } // If we have a work-in-progress fiber, it means there's still work to do // in this root. if (workInProgress !== null) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + var prevExecutionContext = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -16955,8 +18834,8 @@ function renderRoot(root, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) { // Restart at the current time. - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = prevExecutionContext; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; @@ -16980,7 +18859,7 @@ function renderRoot(root, expirationTime, isSync) { break; } catch (thrownValue) { // Reset module-level state that was set during the render phase. - resetContextDependences(); + resetContextDependencies(); resetHooks(); var sourceFiber = workInProgress; @@ -16990,7 +18869,7 @@ function renderRoot(root, expirationTime, isSync) { // supposed to capture all errors that weren't caught by an error // boundary. prepareFreshStack(root, expirationTime); - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; throw thrownValue; } @@ -17013,8 +18892,8 @@ function renderRoot(root, expirationTime, isSync) { } } while (true); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = prevExecutionContext; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; @@ -17034,6 +18913,9 @@ function renderRoot(root, expirationTime, isSync) { // something suspended, wait to commit it after a timeout. stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + var isLocked = resolveLocksOnRoot(root, expirationTime); if (isLocked) { // This root has a lock that prevents it from committing. Exit. If we begin @@ -17045,11 +18927,13 @@ function renderRoot(root, expirationTime, isSync) { // Set this to null to indicate there's no in-progress render. workInProgressRoot = null; + flushSuspensePriorityWarningInDEV(); + switch (workInProgressRootExitStatus) { case RootIncomplete: { (function() { { - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); } })(); } @@ -17059,77 +18943,192 @@ function renderRoot(root, expirationTime, isSync) { case RootErrored: { // An error was thrown. First check if there is lower priority work // scheduled on this root. - var lastPendingTime = root.lastPendingTime; - if (root.lastPendingTime < expirationTime) { + var _lastPendingTime = root.lastPendingTime; + if (_lastPendingTime < expirationTime) { // There's lower priority work. Before raising the error, try rendering // at the lower priority to see if it fixes it. Use a continuation to // maintain the existing priority and position in the queue. - return renderRoot.bind(null, root, lastPendingTime); + return renderRoot.bind(null, root, _lastPendingTime); } if (!isSync) { // If we're rendering asynchronously, it's possible the error was // caused by tearing due to a mutation during an event. Try rendering // one more time without yiedling to events. prepareFreshStack(root, expirationTime); - scheduleCallback( - ImmediatePriority, - renderRoot.bind(null, root, expirationTime) - ); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); return null; } // If we're already rendering synchronously, commit the root in its // errored state. - return commitRoot.bind(null, root, expirationTime); + return commitRoot.bind(null, root); } case RootSuspended: { + // We have an acceptable loading state. We need to figure out if we should + // immediately commit it or wait a bit. + + // If we have processed new updates during this render, we may now have a + // new loading state ready. We want to ensure that we commit that as soon as + // possible. + var hasNotProcessedNewUpdates = + workInProgressRootLatestProcessedExpirationTime === Sync; + if (hasNotProcessedNewUpdates && !isSync) { + // If we have not processed any new updates during this pass, then this is + // either a retry of an existing fallback state or a hidden tree. + // Hidden trees shouldn't be batched with other work and after that's + // fixed it can only be a retry. + // We're going to throttle committing retries so that we don't show too + // many loading states too quickly. + var msUntilTimeout = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); + // Don't bother with a very short suspense time. + if (msUntilTimeout > 10) { + if (workInProgressRootHasPendingPing) { + // This render was pinged but we didn't get to restart earlier so try + // restarting now instead. + prepareFreshStack(root, expirationTime); + return renderRoot.bind(null, root, expirationTime); + } + var _lastPendingTime2 = root.lastPendingTime; + if (_lastPendingTime2 < expirationTime) { + // There's lower priority work. It might be unsuspended. Try rendering + // at that level. + return renderRoot.bind(null, root, _lastPendingTime2); + } + // The render is suspended, it hasn't timed out, and there's no lower + // priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + msUntilTimeout + ); + return null; + } + } + // The work expired. Commit immediately. + return commitRoot.bind(null, root); + } + case RootSuspendedWithDelay: { if (!isSync) { - var _lastPendingTime = root.lastPendingTime; - if (root.lastPendingTime < expirationTime) { + // We're suspended in a state that should be avoided. We'll try to avoid committing + // it for as long as the timeouts let us. + if (workInProgressRootHasPendingPing) { + // This render was pinged but we didn't get to restart earlier so try + // restarting now instead. + prepareFreshStack(root, expirationTime); + return renderRoot.bind(null, root, expirationTime); + } + var _lastPendingTime3 = root.lastPendingTime; + if (_lastPendingTime3 < expirationTime) { // There's lower priority work. It might be unsuspended. Try rendering - // at that level. - return renderRoot.bind(null, root, _lastPendingTime); + // at that level immediately. + return renderRoot.bind(null, root, _lastPendingTime3); } - // If workInProgressRootMostRecentEventTime is Sync, that means we didn't - // track any event times. That can happen if we retried but nothing switched - // from fallback to content. There's no reason to delay doing no work. - if (workInProgressRootMostRecentEventTime !== Sync) { - var msUntilTimeout = computeMsUntilTimeout( - workInProgressRootMostRecentEventTime, - expirationTime + + var _msUntilTimeout = void 0; + if (workInProgressRootLatestSuspenseTimeout !== Sync) { + // We have processed a suspense config whose expiration time we can use as + // the timeout. + _msUntilTimeout = + expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now(); + } else if (workInProgressRootLatestProcessedExpirationTime === Sync) { + // This should never normally happen because only new updates cause + // delayed states, so we should have processed something. However, + // this could also happen in an offscreen tree. + _msUntilTimeout = 0; + } else { + // If we don't have a suspense config, we're going to use a heuristic to + var eventTimeMs = inferTimeFromExpirationTime( + workInProgressRootLatestProcessedExpirationTime ); - // Don't bother with a very short suspense time. - if (msUntilTimeout > 10) { - // The render is suspended, it hasn't timed out, and there's no lower - // priority work to do. Instead of committing the fallback - // immediately, wait for more data to arrive. - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root, expirationTime), - msUntilTimeout - ); - return null; + var currentTimeMs = now(); + var timeUntilExpirationMs = + expirationTimeToMs(expirationTime) - currentTimeMs; + var timeElapsed = currentTimeMs - eventTimeMs; + if (timeElapsed < 0) { + // We get this wrong some time since we estimate the time. + timeElapsed = 0; + } + + _msUntilTimeout = jnd(timeElapsed) - timeElapsed; + + // Clamp the timeout to the expiration time. + // TODO: Once the event time is exact instead of inferred from expiration time + // we don't need this. + if (timeUntilExpirationMs < _msUntilTimeout) { + _msUntilTimeout = timeUntilExpirationMs; } } + + // Don't bother with a very short suspense time. + if (_msUntilTimeout > 10) { + // The render is suspended, it hasn't timed out, and there's no lower + // priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + _msUntilTimeout + ); + return null; + } } // The work expired. Commit immediately. - return commitRoot.bind(null, root, expirationTime); + return commitRoot.bind(null, root); } case RootCompleted: { // The work completed. Ready to commit. - return commitRoot.bind(null, root, expirationTime); + if ( + !isSync && + workInProgressRootLatestProcessedExpirationTime !== Sync && + workInProgressRootCanSuspendUsingConfig !== null + ) { + // If we have exceeded the minimum loading delay, which probably + // means we have shown a spinner already, we might have to suspend + // a bit longer to ensure that the spinner is shown for enough time. + var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay( + workInProgressRootLatestProcessedExpirationTime, + expirationTime, + workInProgressRootCanSuspendUsingConfig + ); + if (_msUntilTimeout2 > 10) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + _msUntilTimeout2 + ); + return null; + } + } + return commitRoot.bind(null, root); } default: { (function() { { - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } })(); } } } -function markRenderEventTime(expirationTime) { - if (expirationTime < workInProgressRootMostRecentEventTime) { - workInProgressRootMostRecentEventTime = expirationTime; +function markCommitTimeOfFallback() { + globalMostRecentFallbackTime = now(); +} + +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + if ( + expirationTime < workInProgressRootLatestProcessedExpirationTime && + expirationTime > Never + ) { + workInProgressRootLatestProcessedExpirationTime = expirationTime; + } + if (suspenseConfig !== null) { + if ( + expirationTime < workInProgressRootLatestSuspenseTimeout && + expirationTime > Never + ) { + workInProgressRootLatestSuspenseTimeout = expirationTime; + // Most of the time we only have one config and getting wrong is not bad. + workInProgressRootCanSuspendUsingConfig = suspenseConfig; + } } } @@ -17139,15 +19138,29 @@ function renderDidSuspend() { } } -function renderDidError() { +function renderDidSuspendDelayIfPossible() { if ( workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended ) { + workInProgressRootExitStatus = RootSuspendedWithDelay; + } +} + +function renderDidError() { + if (workInProgressRootExitStatus !== RootCompleted) { workInProgressRootExitStatus = RootErrored; } } +// Called during render to determine if anything has suspended. +// Returns false if we're not sure. +function renderHasNotSuspendedYet() { + // If something errored or completed, we can't really be sure, + // so those are false. + return workInProgressRootExitStatus === RootIncomplete; +} + function inferTimeFromExpirationTime(expirationTime) { // We don't know exactly when the update was scheduled, but we can infer an // approximate start time from the expiration time. @@ -17155,6 +19168,20 @@ function inferTimeFromExpirationTime(expirationTime) { return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION; } +function inferTimeFromExpirationTimeWithSuspenseConfig( + expirationTime, + suspenseConfig +) { + // We don't know exactly when the update was scheduled, but we can infer an + // approximate start time from the expiration time by subtracting the timeout + // that was added to the event time. + var earliestExpirationTimeMs = expirationTimeToMs(expirationTime); + return ( + earliestExpirationTimeMs - + (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) + ); +} + function workLoopSync() { // Already timed out, so perform work without checking if we need to yield. while (workInProgress !== null) { @@ -17179,7 +19206,7 @@ function performUnitOfWork(unitOfWork) { setCurrentFiber(unitOfWork); var next = void 0; - if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoContext) { + if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); @@ -17215,7 +19242,7 @@ function completeUnitOfWork(unitOfWork) { var next = void 0; if ( !enableProfilerTimer || - (workInProgress.mode & ProfileMode) === NoContext + (workInProgress.mode & ProfileMode) === NoMode ) { next = completeWork(current$$1, workInProgress, renderExpirationTime); } else { @@ -17281,7 +19308,7 @@ function completeUnitOfWork(unitOfWork) { if ( enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoContext + (workInProgress.mode & ProfileMode) !== NoMode ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); @@ -17345,7 +19372,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoContext) { + if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -17398,11 +19425,8 @@ function resetChildExpirationTime(completedWork) { completedWork.childExpirationTime = newChildExpirationTime; } -function commitRoot(root, expirationTime) { - runWithPriority( - ImmediatePriority, - commitRootImpl.bind(null, root, expirationTime) - ); +function commitRoot(root) { + runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root)); // If there are passive effects, schedule a callback to flush them. This goes // outside commitRootImpl so that it inherits the priority of the render. if (rootWithPendingPassiveEffects !== null) { @@ -17415,19 +19439,31 @@ function commitRoot(root, expirationTime) { return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); flushRenderPhaseStrictModeWarningsInDEV(); (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Should not already be working."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError(Error("Should not already be working.")); } })(); - var finishedWork = root.current.alternate; + + var finishedWork = root.finishedWork; + var expirationTime = root.finishedExpirationTime; + if (finishedWork === null) { + return null; + } + root.finishedWork = null; + root.finishedExpirationTime = NoWork; + (function() { - if (!(finishedWork !== null)) { - throw ReactError("Should have a work-in-progress root."); + if (!(finishedWork !== root.current)) { + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); } })(); @@ -17483,8 +19519,8 @@ function commitRootImpl(root, expirationTime) { } if (firstEffect !== null) { - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + var prevExecutionContext = executionContext; + executionContext |= CommitContext; var prevInteractions = null; if (enableSchedulerTracing) { prevInteractions = tracing.__interactionsRef.current; @@ -17510,7 +19546,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var error = clearCaughtError(); @@ -17536,7 +19572,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var _error = clearCaughtError(); @@ -17571,7 +19607,7 @@ function commitRootImpl(root, expirationTime) { if (hasCaughtError()) { (function() { if (!(nextEffect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var _error2 = clearCaughtError(); @@ -17584,10 +19620,14 @@ function commitRootImpl(root, expirationTime) { nextEffect = null; + // Tell Scheduler to yield at the end of the frame, so the browser has an + // opportunity to paint. + requestPaint(); + if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; } - workPhase = prevWorkPhase; + executionContext = prevExecutionContext; } else { // No effects. root.current = finishedWork; @@ -17607,6 +19647,8 @@ function commitRootImpl(root, expirationTime) { stopCommitTimer(); + var rootDidHavePassiveEffects = rootDoesHavePassiveEffects; + if (rootDoesHavePassiveEffects) { // This commit has passive effects. Stash a reference to them. But don't // schedule a callback until after flushing layout work. @@ -17614,11 +19656,14 @@ function commitRootImpl(root, expirationTime) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsExpirationTime = expirationTime; } else { - if (enableSchedulerTracing) { - // If there are no passive effects, then we can complete the pending - // interactions. Otherwise, we'll wait until after the passive effects - // are flushed. - finishPendingInteractions(root, expirationTime); + // 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; + nextEffect = nextNextEffect; } } @@ -17630,6 +19675,21 @@ function commitRootImpl(root, expirationTime) { currentTime, remainingExpirationTime ); + + if (enableSchedulerTracing) { + if (spawnedWorkDuringRender !== null) { + var expirationTimes = spawnedWorkDuringRender; + spawnedWorkDuringRender = null; + for (var i = 0; i < expirationTimes.length; i++) { + scheduleInteractions( + root, + expirationTimes[i], + root.memoizedInteractions + ); + } + } + } + scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime); } else { // If there's no remaining work, we can clear the set of already failed @@ -17637,7 +19697,17 @@ function commitRootImpl(root, expirationTime) { legacyErrorBoundariesThatAlreadyFailed = null; } - onCommitRoot(finishedWork.stateNode); + if (enableSchedulerTracing) { + if (!rootDidHavePassiveEffects) { + // If there are no passive effects, then we can complete the pending interactions. + // Otherwise, we'll wait until after the passive effects are flushed. + // Wait to do this until after remaining work has been scheduled, + // so that we don't prematurely signal complete for interactions when there's e.g. hidden work. + finishPendingInteractions(root, expirationTime); + } + } + + onCommitRoot(finishedWork.stateNode, expirationTime); if (remainingExpirationTime === Sync) { // Count the number of times the root synchronously re-renders without @@ -17659,7 +19729,7 @@ function commitRootImpl(root, expirationTime) { throw _error3; } - if (workPhase === LegacyUnbatchedPhase) { + if ((executionContext & LegacyUnbatchedContext) !== NoContext) { // This is a legacy edge case. We just committed the initial mount of // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired // synchronously, but layout updates should be deferred until the end @@ -17668,7 +19738,7 @@ function commitRootImpl(root, expirationTime) { } // If layout work was scheduled, flush it now. - flushImmediateQueue(); + flushSyncCallbackQueue(); return null; } @@ -17794,12 +19864,14 @@ function flushPassiveEffects() { } (function() { - if (!(workPhase !== RenderPhase && workPhase !== CommitPhase)) { - throw ReactError("Cannot flush passive effects while already rendering."); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); } })(); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + var prevExecutionContext = executionContext; + executionContext |= CommitContext; // 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 @@ -17812,7 +19884,7 @@ function flushPassiveEffects() { if (hasCaughtError()) { (function() { if (!(effect !== null)) { - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); } })(); var error = clearCaughtError(); @@ -17820,7 +19892,10 @@ function flushPassiveEffects() { } resetCurrentFiber(); } - effect = effect.nextEffect; + var nextNextEffect = effect.nextEffect; + // Remove nextEffect pointer to assist GC + effect.nextEffect = null; + effect = nextNextEffect; } if (enableSchedulerTracing) { @@ -17828,8 +19903,8 @@ function flushPassiveEffects() { finishPendingInteractions(root, expirationTime); } - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. @@ -17922,9 +19997,32 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { // Received a ping at the same priority level at which we're currently - // rendering. Restart from the root. Don't need to schedule a ping because - // we're already working on this tree. - prepareFreshStack(root, renderExpirationTime); + // rendering. We might want to restart this render. This should mirror + // the logic of whether or not a root suspends once it completes. + + // TODO: If we're rendering sync either due to Sync, Batched or expired, + // we should probably never restart. + + // If we're suspended with delay, we'll always suspend so we can always + // restart. If we're suspended without any updates, it might be a retry. + // If it's early in the retry we can restart. We can't know for sure + // whether we'll eventually process an update during this render pass, + // but it's somewhat unlikely that we get to a ping before that, since + // getting to the root most update is usually very fast. + if ( + workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + workInProgressRootLatestProcessedExpirationTime === Sync && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ) { + // Restart from the root. Don't need to schedule a ping because + // we're already working on this tree. + prepareFreshStack(root, renderExpirationTime); + } else { + // Even though we can't restart right now, we might get an + // opportunity later. So we mark this render as having a ping. + workInProgressRootHasPendingPing = true; + } return; } @@ -17943,6 +20041,12 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { // Mark the time at which this ping was scheduled. root.pingTime = suspendedTime; + if (root.finishedExpirationTime === suspendedTime) { + // If there's a pending fallback waiting to commit, throw it away. + root.finishedExpirationTime = NoWork; + root.finishedWork = null; + } + var currentTime = requestCurrentTime(); var priorityLevel = inferPriorityFromExpirationTime( currentTime, @@ -17952,12 +20056,17 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { } function retryTimedOutBoundary(boundaryFiber) { - // The boundary fiber (a Suspense component) previously timed out and was - // rendered in its fallback state. One of the promises that suspended it has - // resolved, which means at least part of the tree was likely unblocked. Try - // rendering again, at a new expiration time. + // The boundary fiber (a Suspense component or SuspenseList component) + // previously was rendered in its fallback state. One of the promises that + // suspended it has resolved, which means at least part of the tree was + // likely unblocked. Try rendering again, at a new expiration time. var currentTime = requestCurrentTime(); - var retryTime = computeExpirationForFiber(currentTime, boundaryFiber); + var suspenseConfig = null; // Retries don't carry over the already committed update. + var retryTime = computeExpirationForFiber( + currentTime, + boundaryFiber, + suspenseConfig + ); // TODO: Special case idle priority? var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime); var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime); @@ -17980,7 +20089,9 @@ function resolveRetryThenable(boundaryFiber, thenable) { (function() { { throw ReactError( - "Pinged unknown suspense boundary type. This is probably a bug in React." + Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ) ); } })(); @@ -18023,29 +20134,30 @@ function jnd(timeElapsed) { : ceil(timeElapsed / 1960) * 1960; } -function computeMsUntilTimeout(mostRecentEventTime, committedExpirationTime) { - if (disableYielding) { - // Timeout immediately when yielding is disabled. +function computeMsUntilSuspenseLoadingDelay( + mostRecentEventTime, + committedExpirationTime, + suspenseConfig +) { + var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0; + if (busyMinDurationMs <= 0) { return 0; } + var busyDelayMs = suspenseConfig.busyDelayMs | 0; - var eventTimeMs = inferTimeFromExpirationTime(mostRecentEventTime); + // Compute the time until this render pass would expire. var currentTimeMs = now(); + var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig( + mostRecentEventTime, + suspenseConfig + ); var timeElapsed = currentTimeMs - eventTimeMs; - - var msUntilTimeout = jnd(timeElapsed) - timeElapsed; - - // Compute the time until this render pass would expire. - var timeUntilExpirationMs = - expirationTimeToMs(committedExpirationTime) - currentTimeMs; - - // Clamp the timeout to the expiration time. - // TODO: Once the event time is exact instead of inferred from expiration time - // we don't need this. - if (timeUntilExpirationMs < msUntilTimeout) { - msUntilTimeout = timeUntilExpirationMs; + if (timeElapsed <= busyDelayMs) { + // If we haven't yet waited longer than the initial delay, we don't + // have to wait any additional time. + return 0; } - + var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`. return msUntilTimeout; } @@ -18057,7 +20169,9 @@ function checkForNestedUpdates() { (function() { { throw ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) ); } })(); @@ -18079,11 +20193,10 @@ function checkForNestedUpdates() { function flushRenderPhaseStrictModeWarningsInDEV() { { - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); ReactStrictModeWarnings.flushLegacyContextWarning(); if (warnAboutDeprecatedLifecycles) { - ReactStrictModeWarnings.flushPendingDeprecationWarnings(); + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } } @@ -18178,7 +20291,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // Keep this code in sync with renderRoot; any changes here must have // corresponding changes there. - resetContextDependences(); + resetContextDependencies(); resetHooks(); // Unwind the failed stack frame @@ -18243,585 +20356,509 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { "within `render`). Render methods should be a pure function of " + "props and state." ); - didWarnAboutUpdateInRender = true; - break; - } - } - } -} - -function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { - { - if ( - workPhase === NotWorking && - ReactShouldWarnActingUpdates.current === false - ) { - warningWithoutStack$1( - false, - "An update to %s inside a test was not wrapped in act(...).\n\n" + - "When testing, code that causes React state updates should be " + - "wrapped into act(...):\n\n" + - "act(() => {\n" + - " /* fire events that update state */\n" + - "});\n" + - "/* assert on the output */\n\n" + - "This ensures that you're testing the behavior the user would see " + - "in the browser." + - " Learn more at https://fb.me/react-wrap-tests-with-act" + - "%s", - getComponentName(fiber.type), - getStackByFiberInDevAndProd(fiber) - ); - } - } -} - -var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; - -function computeThreadID(root, expirationTime) { - // Interaction threads are unique per root and expiration time. - return expirationTime * 1000 + root.interactionThreadID; -} - -function schedulePendingInteraction(root, expirationTime) { - // This is called when work is scheduled on a root. It sets up a pending - // interaction, which is completed once the work commits. - if (!enableSchedulerTracing) { - return; - } - - var interactions = tracing.__interactionsRef.current; - if (interactions.size > 0) { - var pendingInteractionMap = root.pendingInteractionMap; - var pendingInteractions = pendingInteractionMap.get(expirationTime); - if (pendingInteractions != null) { - interactions.forEach(function(interaction) { - if (!pendingInteractions.has(interaction)) { - // Update the pending async work count for previously unscheduled interaction. - interaction.__count++; - } - - pendingInteractions.add(interaction); - }); - } else { - pendingInteractionMap.set(expirationTime, new Set(interactions)); - - // Update the pending async work count for the current interactions. - interactions.forEach(function(interaction) { - interaction.__count++; - }); - } - - var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { - var threadID = computeThreadID(root, expirationTime); - subscriber.onWorkScheduled(interactions, threadID); - } - } -} - -function startWorkOnPendingInteraction(root, expirationTime) { - // This is called when new work is started on a root. - if (!enableSchedulerTracing) { - return; - } - - // Determine which interactions this batch of work currently includes, So that - // we can accurately attribute time spent working on it, And so that cascading - // work triggered during the render phase will be associated with it. - var interactions = new Set(); - root.pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledExpirationTime - ) { - if (scheduledExpirationTime >= expirationTime) { - scheduledInteractions.forEach(function(interaction) { - return interactions.add(interaction); - }); - } - }); - - // Store the current set of interactions on the FiberRoot for a few reasons: - // We can re-use it in hot functions like renderRoot() without having to - // recalculate it. We will also use it in commitWork() to pass to any Profiler - // onRender() hooks. This also provides DevTools with a way to access it when - // the onCommitRoot() hook is called. - root.memoizedInteractions = interactions; - - if (interactions.size > 0) { - var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { - var threadID = computeThreadID(root, expirationTime); - try { - subscriber.onWorkStarted(interactions, threadID); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); + didWarnAboutUpdateInRender = true; + break; } } } } -function finishPendingInteractions(root, committedExpirationTime) { - if (!enableSchedulerTracing) { - return; - } - - var earliestRemainingTimeAfterCommit = root.firstPendingTime; - - var subscriber = void 0; +var IsThisRendererActing = { current: false }; - try { - subscriber = tracing.__subscriberRef.current; - if (subscriber !== null && root.memoizedInteractions.size > 0) { - var threadID = computeThreadID(root, committedExpirationTime); - subscriber.onWorkStopped(root.memoizedInteractions, threadID); - } - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } finally { - // Clear completed interactions from the pending Map. - // Unless the render was suspended or cascading work was scheduled, - // In which case– leave pending interactions until the subsequent render. - var pendingInteractionMap = root.pendingInteractionMap; - pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledExpirationTime +function warnIfNotScopedWithMatchingAct(fiber) { + { + if ( + warnsIfNotActing === true && + IsSomeRendererActing.current === true && + IsThisRendererActing.current !== true ) { - // Only decrement the pending interaction count if we're done. - // If there's still work at the current priority, - // That indicates that we are waiting for suspense data. - if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { - pendingInteractionMap.delete(scheduledExpirationTime); - - scheduledInteractions.forEach(function(interaction) { - interaction.__count--; - - if (subscriber !== null && interaction.__count === 0) { - try { - subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } - } - }); - } - }); + warningWithoutStack$1( + false, + "It looks like you're using the wrong act() around your test interactions.\n" + + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + + "// for react-dom:\n" + + "import {act} from 'react-dom/test-utils';\n" + + "//...\n" + + "act(() => ...);\n\n" + + "// for react-test-renderer:\n" + + "import TestRenderer from 'react-test-renderer';\n" + + "const {act} = TestRenderer;\n" + + "//...\n" + + "act(() => ...);" + + "%s", + getStackByFiberInDevAndProd(fiber) + ); + } } } -// Resolves type to a family. - -// Used by React Refresh runtime through DevTools Global Hook. - -var resolveFamily = null; -// $FlowFixMe Flow gets confused by a WeakSet feature check below. -var failedBoundaries = null; - -var setRefreshHandler = function(handler) { +function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { - resolveFamily = handler; + if ( + warnsIfNotActing === true && + (fiber.mode & StrictMode) !== NoMode && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); + } } -}; +} -function resolveFunctionForHotReloading(type) { +function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return type; - } - var family = resolveFamily(type); - if (family === undefined) { - return type; + if ( + warnsIfNotActing === true && + executionContext === NoContext && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s inside a test was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); } - // Use the latest known implementation. - return family.current; } } -function resolveClassForHotReloading(type) { - // No implementation differences. - return resolveFunctionForHotReloading(type); -} +var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; -function resolveForwardRefForHotReloading(type) { +var componentsThatSuspendedAtHighPri = null; +var componentsThatTriggeredHighPriSuspend = null; +function checkForWrongSuspensePriorityInDEV(sourceFiber) { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return type; - } - var family = resolveFamily(type); - if (family === undefined) { - // Check if we're dealing with a real forwardRef. Don't want to crash early. - if ( - type !== null && - type !== undefined && - typeof type.render === "function" - ) { - // ForwardRef is special because its resolved .type is an object, - // but it's possible that we only have its inner render function in the map. - // If that inner render function is different, we'll build a new forwardRef type. - var currentRender = resolveFunctionForHotReloading(type.render); - if (type.render !== currentRender) { - var syntheticType = { - $$typeof: REACT_FORWARD_REF_TYPE, - render: currentRender - }; - if (type.displayName !== undefined) { - syntheticType.displayName = type.displayName; + var currentPriorityLevel = getCurrentPriorityLevel(); + if ( + (sourceFiber.mode & ConcurrentMode) !== NoEffect && + (currentPriorityLevel === UserBlockingPriority || + currentPriorityLevel === ImmediatePriority) + ) { + var workInProgressNode = sourceFiber; + while (workInProgressNode !== null) { + // Add the component that triggered the suspense + var current$$1 = workInProgressNode.alternate; + if (current$$1 !== null) { + // TODO: warn component that triggers the high priority + // suspend is the HostRoot + switch (workInProgressNode.tag) { + case ClassComponent: + // Loop through the component's update queue and see whether the component + // has triggered any high priority updates + var updateQueue = current$$1.updateQueue; + if (updateQueue !== null) { + var update = updateQueue.firstUpdate; + while (update !== null) { + var priorityLevel = update.priority; + if ( + priorityLevel === UserBlockingPriority || + priorityLevel === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + break; + } + update = update.next; + } + } + break; + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if ( + workInProgressNode.memoizedState !== null && + workInProgressNode.memoizedState.baseUpdate !== null + ) { + var _update = workInProgressNode.memoizedState.baseUpdate; + // Loop through the functional component's memoized state to see whether + // the component has triggered any high pri updates + while (_update !== null) { + var priority = _update.priority; + if ( + priority === UserBlockingPriority || + priority === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + break; + } + if ( + _update.next === workInProgressNode.memoizedState.baseUpdate + ) { + break; + } + _update = _update.next; + } + } + break; + default: + break; } - return syntheticType; } + workInProgressNode = workInProgressNode.return; + } + + // Add the component name to a set. + var componentName = getComponentName(sourceFiber.type); + if (componentsThatSuspendedAtHighPri === null) { + componentsThatSuspendedAtHighPri = new Set([componentName]); + } else { + componentsThatSuspendedAtHighPri.add(componentName); } - return type; } - // Use the latest known implementation. - return family.current; } } -function isCompatibleFamilyForHotReloading(fiber, element) { +function flushSuspensePriorityWarningInDEV() { { - if (resolveFamily === null) { - // Hot reloading is disabled. - return false; + if (componentsThatSuspendedAtHighPri !== null) { + var componentNames = []; + componentsThatSuspendedAtHighPri.forEach(function(name) { + componentNames.push(name); + }); + componentsThatSuspendedAtHighPri = null; + + var componentsThatTriggeredSuspendNames = []; + if (componentsThatTriggeredHighPriSuspend !== null) { + componentsThatTriggeredHighPriSuspend.forEach(function(name) { + return componentsThatTriggeredSuspendNames.push(name); + }); + } + + componentsThatTriggeredHighPriSuspend = null; + + var componentNamesString = componentNames.sort().join(", "); + var componentThatTriggeredSuspenseError = ""; + if (componentsThatTriggeredSuspendNames.length > 0) { + componentThatTriggeredSuspenseError = + "The following components triggered a user-blocking update:" + + "\n\n" + + " " + + componentsThatTriggeredSuspendNames.sort().join(", ") + + "\n\n" + + "that was then suspended by:" + + "\n\n" + + " " + + componentNamesString; + } else { + componentThatTriggeredSuspenseError = + "A user-blocking update was suspended by:" + + "\n\n" + + " " + + componentNamesString; + } + + warningWithoutStack$1( + false, + "%s" + + "\n\n" + + "The fix is to split the update into multiple parts: a user-blocking " + + "update to provide immediate feedback, and another update that " + + "triggers the bulk of the changes." + + "\n\n" + + "Refer to the documentation for useSuspenseTransition to learn how " + + "to implement this pattern.", + // TODO: Add link to React docs with more information, once it exists + componentThatTriggeredSuspenseError + ); } + } +} - var prevType = fiber.elementType; - var nextType = element.type; +function computeThreadID(root, expirationTime) { + // Interaction threads are unique per root and expiration time. + return expirationTime * 1000 + root.interactionThreadID; +} - // If we got here, we know types aren't === equal. - var needsCompareFamilies = false; +function markSpawnedWork(expirationTime) { + if (!enableSchedulerTracing) { + return; + } + if (spawnedWorkDuringRender === null) { + spawnedWorkDuringRender = [expirationTime]; + } else { + spawnedWorkDuringRender.push(expirationTime); + } +} - var $$typeofNextType = - typeof nextType === "object" && nextType !== null - ? nextType.$$typeof - : null; +function scheduleInteractions(root, expirationTime, interactions) { + if (!enableSchedulerTracing) { + return; + } - switch (fiber.tag) { - case ClassComponent: { - if (typeof nextType === "function") { - needsCompareFamilies = true; - } - break; - } - case FunctionComponent: { - if (typeof nextType === "function") { - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - // We don't know the inner type yet. - // We're going to assume that the lazy inner type is stable, - // and so it is sufficient to avoid reconciling it away. - // We're not going to unwrap or actually use the new lazy type. - needsCompareFamilies = true; - } - break; - } - case ForwardRef: { - if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - needsCompareFamilies = true; - } - break; - } - case MemoComponent: - case SimpleMemoComponent: { - if ($$typeofNextType === REACT_MEMO_TYPE) { - // TODO: if it was but can no longer be simple, - // we shouldn't set this. - needsCompareFamilies = true; - } else if ($$typeofNextType === REACT_LAZY_TYPE) { - needsCompareFamilies = true; + if (interactions.size > 0) { + var pendingInteractionMap = root.pendingInteractionMap; + var pendingInteractions = pendingInteractionMap.get(expirationTime); + if (pendingInteractions != null) { + interactions.forEach(function(interaction) { + if (!pendingInteractions.has(interaction)) { + // Update the pending async work count for previously unscheduled interaction. + interaction.__count++; } - break; - } - default: - return false; + + pendingInteractions.add(interaction); + }); + } else { + pendingInteractionMap.set(expirationTime, new Set(interactions)); + + // Update the pending async work count for the current interactions. + interactions.forEach(function(interaction) { + interaction.__count++; + }); } - // Check if both types have a family and it's the same one. - if (needsCompareFamilies) { - // Note: memo() and forwardRef() we'll compare outer rather than inner type. - // This means both of them need to be registered to preserve state. - // If we unwrapped and compared the inner types for wrappers instead, - // then we would risk falsely saying two separate memo(Foo) - // calls are equivalent because they wrap the same Foo function. - var prevFamily = resolveFamily(prevType); - if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { - return true; - } + var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { + var threadID = computeThreadID(root, expirationTime); + subscriber.onWorkScheduled(interactions, threadID); } - return false; } } -function markFailedErrorBoundaryForHotReloading(fiber) { - { - if (resolveFamily === null) { - // Hot reloading is disabled. - return; - } - if (typeof WeakSet !== "function") { - return; - } - if (failedBoundaries === null) { - failedBoundaries = new WeakSet(); - } - failedBoundaries.add(fiber); +function schedulePendingInteractions(root, expirationTime) { + // This is called when work is scheduled on a root. + // It associates the current interactions with the newly-scheduled expiration. + // They will be restored when that expiration is later committed. + if (!enableSchedulerTracing) { + return; } -} - -var scheduleRefresh = function(root, update) { - { - if (resolveFamily === null) { - // Hot reloading is disabled. - return; - } - var _staleFamilies = update.staleFamilies, - _updatedFamilies = update.updatedFamilies; - flushPassiveEffects(); - flushSync(function() { - scheduleFibersWithFamiliesRecursively( - root.current, - _updatedFamilies, - _staleFamilies - ); - }); - } -}; + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); +} -var scheduleRoot = function(root, element) { - { - if (root.context !== emptyContextObject) { - // Super edge case: root has a legacy _renderSubtree context - // but we don't know the parentComponent so we can't pass it. - // Just ignore. We'll delete this with _renderSubtree code path later. - return; - } - flushPassiveEffects(); - updateContainerAtExpirationTime(element, root, null, Sync, null); +function startWorkOnPendingInteractions(root, expirationTime) { + // This is called when new work is started on a root. + if (!enableSchedulerTracing) { + return; } -}; - -function scheduleFibersWithFamiliesRecursively( - fiber, - updatedFamilies, - staleFamilies -) { - { - var alternate = fiber.alternate, - child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type; - var candidateType = null; - switch (tag) { - case FunctionComponent: - case SimpleMemoComponent: - case ClassComponent: - candidateType = type; - break; - case ForwardRef: - candidateType = type.render; - break; - default: - break; + // Determine which interactions this batch of work currently includes, So that + // we can accurately attribute time spent working on it, And so that cascading + // work triggered during the render phase will be associated with it. + var interactions = new Set(); + root.pendingInteractionMap.forEach(function( + scheduledInteractions, + scheduledExpirationTime + ) { + if (scheduledExpirationTime >= expirationTime) { + scheduledInteractions.forEach(function(interaction) { + return interactions.add(interaction); + }); } + }); - if (resolveFamily === null) { - throw new Error("Expected resolveFamily to be set during hot reload."); - } + // Store the current set of interactions on the FiberRoot for a few reasons: + // We can re-use it in hot functions like renderRoot() without having to + // recalculate it. We will also use it in commitWork() to pass to any Profiler + // onRender() hooks. This also provides DevTools with a way to access it when + // the onCommitRoot() hook is called. + root.memoizedInteractions = interactions; - var needsRender = false; - var needsRemount = false; - if (candidateType !== null) { - var family = resolveFamily(candidateType); - if (family !== undefined) { - if (staleFamilies.has(family)) { - needsRemount = true; - } else if (updatedFamilies.has(family)) { - needsRender = true; - } - } - } - if (failedBoundaries !== null) { - if ( - failedBoundaries.has(fiber) || - (alternate !== null && failedBoundaries.has(alternate)) - ) { - needsRemount = true; + if (interactions.size > 0) { + var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { + var threadID = computeThreadID(root, expirationTime); + try { + subscriber.onWorkStarted(interactions, threadID); + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); } } - - if (needsRemount) { - fiber._debugNeedsRemount = true; - } - if (needsRemount || needsRender) { - scheduleWork(fiber, Sync); - } - if (child !== null && !needsRemount) { - scheduleFibersWithFamiliesRecursively( - child, - updatedFamilies, - staleFamilies - ); - } - if (sibling !== null) { - scheduleFibersWithFamiliesRecursively( - sibling, - updatedFamilies, - staleFamilies - ); - } } } -var findHostInstancesForRefresh = function(root, families) { - { - var hostInstances = new Set(); - var types = new Set( - families.map(function(family) { - return family.current; - }) - ); - findHostInstancesForMatchingFibersRecursively( - root.current, - types, - hostInstances - ); - return hostInstances; +function finishPendingInteractions(root, committedExpirationTime) { + if (!enableSchedulerTracing) { + return; } -}; -function findHostInstancesForMatchingFibersRecursively( - fiber, - types, - hostInstances -) { - { - var child = fiber.child, - sibling = fiber.sibling, - tag = fiber.tag, - type = fiber.type; + var earliestRemainingTimeAfterCommit = root.firstPendingTime; - var candidateType = null; - switch (tag) { - case FunctionComponent: - case SimpleMemoComponent: - case ClassComponent: - candidateType = type; - break; - case ForwardRef: - candidateType = type.render; - break; - default: - break; - } + var subscriber = void 0; - var didMatch = false; - if (candidateType !== null) { - if (types.has(candidateType)) { - didMatch = true; - } + try { + subscriber = tracing.__subscriberRef.current; + if (subscriber !== null && root.memoizedInteractions.size > 0) { + var threadID = computeThreadID(root, committedExpirationTime); + subscriber.onWorkStopped(root.memoizedInteractions, threadID); } + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } finally { + // Clear completed interactions from the pending Map. + // Unless the render was suspended or cascading work was scheduled, + // In which case– leave pending interactions until the subsequent render. + var pendingInteractionMap = root.pendingInteractionMap; + pendingInteractionMap.forEach(function( + scheduledInteractions, + scheduledExpirationTime + ) { + // Only decrement the pending interaction count if we're done. + // If there's still work at the current priority, + // That indicates that we are waiting for suspense data. + if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { + pendingInteractionMap.delete(scheduledExpirationTime); - if (didMatch) { - // We have a match. This only drills down to the closest host components. - // There's no need to search deeper because for the purpose of giving - // visual feedback, "flashing" outermost parent rectangles is sufficient. - findHostInstancesForFiberShallowly(fiber, hostInstances); - } else { - // If there's no match, maybe there will be one further down in the child tree. - if (child !== null) { - findHostInstancesForMatchingFibersRecursively( - child, - types, - hostInstances - ); + scheduledInteractions.forEach(function(interaction) { + interaction.__count--; + + if (subscriber !== null && interaction.__count === 0) { + try { + subscriber.onInteractionScheduledWorkCompleted(interaction); + } catch (error) { + // If the subscriber throws, rethrow it in a separate task + scheduleCallback(ImmediatePriority, function() { + throw error; + }); + } + } + }); } - } - - if (sibling !== null) { - findHostInstancesForMatchingFibersRecursively( - sibling, - types, - hostInstances - ); - } + }); } } -function findHostInstancesForFiberShallowly(fiber, hostInstances) { - { - var foundHostInstances = findChildHostInstancesForFiberShallowly( - fiber, - hostInstances - ); - if (foundHostInstances) { - return; +var onCommitFiberRoot = null; +var onCommitFiberUnmount = 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; + } + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + 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) { + { + warningWithoutStack$1( + false, + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://fb.me/react-devtools" + ); } - // If we didn't find any host children, fallback to closest host parent. - var node = fiber; - while (true) { - switch (node.tag) { - case HostComponent: - hostInstances.add(node.stateNode); - return; - case HostPortal: - hostInstances.add(node.stateNode.containerInfo); - return; - case HostRoot: - hostInstances.add(node.stateNode.containerInfo); - return; + // DevTools exists, even though it doesn't support Fiber. + return true; + } + try { + var rendererID = hook.inject(internals); + // We have successfully injected, so now it is safe to set up hooks. + onCommitFiberRoot = function(root, expirationTime) { + try { + var didError = (root.current.effectTag & DidCapture) === DidCapture; + if (enableProfilerTimer) { + var currentTime = requestCurrentTime(); + var priorityLevel = inferPriorityFromExpirationTime( + currentTime, + expirationTime + ); + hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); + } else { + hook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); + } } - if (node.return === null) { - throw new Error("Expected to reach root first."); + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); + } } - node = node.return; + }; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s.", + err + ); } } + // DevTools exists + return true; } -function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { - { - var node = fiber; - var foundHostInstances = false; - while (true) { - if (node.tag === HostComponent) { - // We got a match. - foundHostInstances = true; - hostInstances.add(node.stateNode); - // There may still be more, so keep searching. - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - if (node === fiber) { - return foundHostInstances; - } - while (node.sibling === null) { - if (node.return === null || node.return === fiber) { - return foundHostInstances; - } - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } +function onCommitRoot(root, expirationTime) { + if (typeof onCommitFiberRoot === "function") { + onCommitFiberRoot(root, expirationTime); + } +} + +function onCommitUnmount(fiber) { + if (typeof onCommitFiberUnmount === "function") { + onCommitFiberUnmount(fiber); } - return false; } var hasBadMapPolyfill = void 0; @@ -18872,7 +20909,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.memoizedProps = null; this.updateQueue = null; this.memoizedState = null; - this.contextDependencies = null; + this.dependencies = null; this.mode = mode; @@ -19032,7 +21069,19 @@ function createWorkInProgress(current, pendingProps, expirationTime) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + + // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + expirationTime: currentDependencies.expirationTime, + firstContext: currentDependencies.firstContext, + listeners: currentDependencies.listeners, + responders: currentDependencies.responders + }; // These will be overridden during the parent's reconciliation workInProgress.sibling = current.sibling; @@ -19066,8 +21115,87 @@ function createWorkInProgress(current, pendingProps, expirationTime) { return workInProgress; } -function createHostRootFiber(isConcurrent) { - var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext; +// Used to reuse a Fiber for a second pass. +function resetWorkInProgress(workInProgress, renderExpirationTime) { + // This resets the Fiber to what createFiber or createWorkInProgress would + // have set the values to before during the first pass. Ideally this wouldn't + // be necessary but unfortunately many code paths reads from the workInProgress + // 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 + // that child fiber is setting, not the reconciliation. + workInProgress.effectTag &= Placement; + + // The effect list is no longer valid. + workInProgress.nextEffect = null; + workInProgress.firstEffect = null; + workInProgress.lastEffect = null; + + var current = workInProgress.alternate; + if (current === null) { + // Reset to createFiber's initial values. + workInProgress.childExpirationTime = NoWork; + workInProgress.expirationTime = renderExpirationTime; + + workInProgress.child = null; + workInProgress.memoizedProps = null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + + workInProgress.dependencies = null; + + if (enableProfilerTimer) { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = 0; + workInProgress.treeBaseDuration = 0; + } + } else { + // Reset to the cloned values that createWorkInProgress would've. + workInProgress.childExpirationTime = current.childExpirationTime; + workInProgress.expirationTime = current.expirationTime; + + workInProgress.child = current.child; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; + + // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = + currentDependencies === null + ? null + : { + expirationTime: currentDependencies.expirationTime, + firstContext: currentDependencies.firstContext, + listeners: currentDependencies.listeners, + responders: currentDependencies.responders + }; + + if (enableProfilerTimer) { + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; + } + } + + return workInProgress; +} + +function createHostRootFiber(tag) { + var mode = void 0; + if (tag === ConcurrentRoot) { + mode = ConcurrentMode | BatchedMode | StrictMode; + } else if (tag === BatchedRoot) { + mode = BatchedMode | StrictMode; + } else { + mode = NoMode; + } if (enableProfilerTimer && isDevToolsPresent) { // Always collect profile timings when DevTools are present. @@ -19115,23 +21243,24 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode( - pendingProps, - mode | ConcurrentMode | StrictMode, - expirationTime, - key - ); + fiberTag = Mode; + mode |= ConcurrentMode | BatchedMode | StrictMode; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode( - pendingProps, - mode | StrictMode, - expirationTime, - key - ); + fiberTag = Mode; + mode |= StrictMode; + break; case REACT_PROFILER_TYPE: return createFiberFromProfiler(pendingProps, mode, expirationTime, key); case REACT_SUSPENSE_TYPE: return createFiberFromSuspense(pendingProps, mode, expirationTime, key); + case REACT_SUSPENSE_LIST_TYPE: + return createFiberFromSuspenseList( + pendingProps, + mode, + expirationTime, + key + ); default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -19155,20 +21284,9 @@ function createFiberFromTypeAndProps( fiberTag = LazyComponent; resolvedType = null; break getTag; - case REACT_EVENT_COMPONENT_TYPE: - if (enableEventAPI) { - return createFiberFromEventComponent( - type, - pendingProps, - mode, - expirationTime, - key - ); - } - break; - case REACT_EVENT_TARGET_TYPE: - if (enableEventAPI) { - return createFiberFromEventTarget( + case REACT_FUNDAMENTAL_TYPE: + if (enableFundamentalAPI) { + return createFiberFromFundamental( type, pendingProps, mode, @@ -19200,10 +21318,12 @@ function createFiberFromTypeAndProps( (function() { { throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (type == null ? type : typeof type) + - "." + - info + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (type == null ? type : typeof type) + + "." + + info + ) ); } })(); @@ -19248,35 +21368,17 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { return fiber; } -function createFiberFromEventComponent( - eventComponent, - pendingProps, - mode, - expirationTime, - key -) { - var fiber = createFiber(EventComponent, pendingProps, key, mode); - fiber.elementType = eventComponent; - fiber.type = eventComponent; - fiber.expirationTime = expirationTime; - return fiber; -} - -function createFiberFromEventTarget( - eventTarget, +function createFiberFromFundamental( + fundamentalComponent, pendingProps, mode, expirationTime, key ) { - var fiber = createFiber(EventTarget, pendingProps, key, mode); - fiber.elementType = eventTarget; - fiber.type = eventTarget; + var fiber = createFiber(FundamentalComponent, pendingProps, key, mode); + fiber.elementType = fundamentalComponent; + fiber.type = fundamentalComponent; fiber.expirationTime = expirationTime; - // Store latest props - fiber.stateNode = { - props: pendingProps - }; return fiber; } @@ -19302,29 +21404,28 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { return fiber; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - var fiber = createFiber(Mode, pendingProps, key, mode); +function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { + var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); - // TODO: The Mode fiber shouldn't have a type. It has a tag. - var type = - (mode & ConcurrentMode) === NoContext - ? REACT_STRICT_MODE_TYPE - : REACT_CONCURRENT_MODE_TYPE; - fiber.elementType = type; - fiber.type = type; + // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + fiber.type = REACT_SUSPENSE_TYPE; + fiber.elementType = REACT_SUSPENSE_TYPE; fiber.expirationTime = expirationTime; return fiber; } -function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { - var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); - - // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. - var type = REACT_SUSPENSE_TYPE; - fiber.elementType = type; - fiber.type = type; - +function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) { + var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode); + { + // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag. + // This needs to be fixed in getComponentName so that it relies on the tag + // instead. + fiber.type = REACT_SUSPENSE_LIST_TYPE; + } + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; fiber.expirationTime = expirationTime; return fiber; } @@ -19336,7 +21437,7 @@ function createFiberFromText(content, mode, expirationTime) { } function createFiberFromHostInstanceForDeletion() { - var fiber = createFiber(HostComponent, null, null, NoContext); + var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. fiber.elementType = "DELETED"; fiber.type = "DELETED"; @@ -19360,7 +21461,7 @@ function assignFiberPropertiesInDEV(target, source) { if (target === null) { // This Fiber's initial properties will always be overwritten. // We only use a Fiber to ensure the same hidden class so DEV isn't slow. - target = createFiber(IndeterminateComponent, null, null, NoContext); + target = createFiber(IndeterminateComponent, null, null, NoMode); } // This is intentionally written as a list of all properties. @@ -19383,7 +21484,7 @@ function assignFiberPropertiesInDEV(target, source) { target.memoizedProps = source.memoizedProps; target.updateQueue = source.updateQueue; target.memoizedState = source.memoizedState; - target.contextDependencies = source.contextDependencies; + target.dependencies = source.dependencies; target.mode = source.mode; target.effectTag = source.effectTag; target.nextEffect = source.nextEffect; @@ -19420,12 +21521,13 @@ function assignFiberPropertiesInDEV(target, source) { // The types are defined separately within this file to ensure they stay in sync. // (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.) -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pendingChildren = null; this.pingCache = null; - this.pendingCommitExpirationTime = NoWork; + this.finishedExpirationTime = NoWork; this.finishedWork = null; this.timeoutHandle = noTimeout; this.context = null; @@ -19445,12 +21547,12 @@ function FiberRootNode(containerInfo, hydrate) { } } -function createFiberRoot(containerInfo, isConcurrent, hydrate) { - var root = new FiberRootNode(containerInfo, hydrate); +function createFiberRoot(containerInfo, tag, hydrate) { + var root = new FiberRootNode(containerInfo, tag, hydrate); // Cyclic construction. This cheats the type system right now because // stateNode is any. - var uninitializedFiber = createHostRootFiber(isConcurrent); + var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -19496,7 +21598,13 @@ function getContextForSubtree(parentComponent) { return parentContext; } -function scheduleRootUpdate(current$$1, element, expirationTime, callback) { +function scheduleRootUpdate( + current$$1, + element, + expirationTime, + suspenseConfig, + callback +) { { if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; @@ -19511,7 +21619,7 @@ function scheduleRootUpdate(current$$1, element, expirationTime, callback) { } } - var update = createUpdate(expirationTime); + var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property // being called "element". update.payload = { element: element }; @@ -19529,7 +21637,9 @@ function scheduleRootUpdate(current$$1, element, expirationTime, callback) { update.callback = callback; } - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } enqueueUpdate(current$$1, update); scheduleWork(current$$1, expirationTime); @@ -19541,6 +21651,7 @@ function updateContainerAtExpirationTime( container, parentComponent, expirationTime, + suspenseConfig, callback ) { // TODO: If this is a nested container, this won't be the root. @@ -19565,7 +21676,13 @@ function updateContainerAtExpirationTime( container.pendingContext = context; } - return scheduleRootUpdate(current$$1, element, expirationTime, callback); + return scheduleRootUpdate( + current$$1, + element, + expirationTime, + suspenseConfig, + callback + ); } function findHostInstance(component) { @@ -19574,15 +21691,19 @@ function findHostInstance(component) { if (typeof component.render === "function") { (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } else { (function() { { throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } })(); @@ -19602,15 +21723,19 @@ function findHostInstanceWithWarning(component, methodName) { if (typeof component.render === "function") { (function() { { - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError( + Error("Unable to find node on an unmounted component.") + ); } })(); } else { (function() { { throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } })(); @@ -19660,19 +21785,31 @@ function findHostInstanceWithWarning(component, methodName) { return findHostInstance(component); } -function createContainer(containerInfo, isConcurrent, hydrate) { - return createFiberRoot(containerInfo, isConcurrent, hydrate); +function createContainer(containerInfo, tag, hydrate) { + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current; var currentTime = requestCurrentTime(); - var expirationTime = computeExpirationForFiber(currentTime, current$$1); + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(current$$1); + } + } + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); return updateContainerAtExpirationTime( element, container, parentComponent, expirationTime, + suspenseConfig, callback ); } @@ -19729,7 +21866,9 @@ var setSuspenseHandler = null; id--; } if (currentHook !== null) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } var newState = copyWithSet(currentHook.memoizedState, path, value); currentHook.memoizedState = newState; @@ -19748,7 +21887,9 @@ var setSuspenseHandler = null; // Support DevTools props for function components, forwardRef, memo, host components, etc. overrideProps = function(fiber, path, value) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); if (fiber.alternate) { fiber.alternate.pendingProps = fiber.pendingProps; @@ -19757,7 +21898,9 @@ var setSuspenseHandler = null; }; scheduleUpdate = function(fiber) { - flushPassiveEffects(); + if (revertPassiveEffectsChange) { + flushPassiveEffects(); + } scheduleWork(fiber, Sync); }; @@ -19796,7 +21939,11 @@ function injectIntoDevTools(devToolsConfig) { findHostInstancesForRefresh: findHostInstancesForRefresh, scheduleRefresh: scheduleRefresh, scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: function() { + return current; + } }) ); } @@ -20113,7 +22260,7 @@ var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps ) ) { - throw ReactError("Do not override existing functions."); + throw ReactError(Error("Do not override existing functions.")); } })(); // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, @@ -20471,9 +22618,9 @@ var ReactNativeComponent = function(findNodeHandle, findHostInstance) { }; // Module provided by RN: -var emptyObject$1 = {}; +var emptyObject$2 = {}; { - Object.freeze(emptyObject$1); + Object.freeze(emptyObject$2); } var getInspectorDataForViewTag = void 0; @@ -20506,9 +22653,9 @@ var getInspectorDataForViewTag = void 0; var getHostProps = function(fiber) { var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$1; + return host.memoizedProps || emptyObject$2; } - return emptyObject$1; + return emptyObject$2; }; var getHostNode = function(fiber, findNodeHandle) { @@ -20554,7 +22701,7 @@ var getInspectorDataForViewTag = void 0; if (!closestInstance) { return { hierarchy: [], - props: emptyObject$1, + props: emptyObject$2, selection: null, source: null }; @@ -20663,8 +22810,9 @@ function findNodeHandle(componentOrHandle) { setBatchingImplementation( batchedUpdates$1, - interactiveUpdates$1, - flushInteractiveUpdates$1 + discreteUpdates$1, + flushDiscreteUpdates, + batchedEventUpdates$1 ); function computeComponentStackForErrorReporting(reactTag) { @@ -20682,6 +22830,25 @@ var ReactNativeRenderer = { findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + if (handle._nativeTag == null) { + !(handle._nativeTag != null) + ? warningWithoutStack$1( + false, + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ) + : void 0; + return; + } + + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + }, + setNativeProps: setNativeProps, render: function(element, containerTag, callback) { @@ -20690,7 +22857,7 @@ var ReactNativeRenderer = { 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, false, false); + root = createContainer(containerTag, LegacyRoot, false); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index 409f8abc67b89b..9437badd089b1c 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -14,10 +14,9 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -function ReactError(message) { - message = Error(message); - message.name = "Invariant Violation"; - return message; +function ReactError(error) { + error.name = "Invariant Violation"; + return error; } var eventPluginOrder = null, namesToPlugins = {}; @@ -28,16 +27,20 @@ function recomputePluginOrdering() { pluginIndex = eventPluginOrder.indexOf(pluginName); if (!(-1 < pluginIndex)) throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); if (!plugins[pluginIndex]) { if (!pluginModule.extractEvents) throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); plugins[pluginIndex] = pluginModule; pluginIndex = pluginModule.eventTypes; @@ -48,9 +51,11 @@ function recomputePluginOrdering() { eventName$jscomp$0 = eventName; if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ) ); eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -76,11 +81,13 @@ function recomputePluginOrdering() { : (JSCompiler_inline_result = !1); if (!JSCompiler_inline_result) throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } } @@ -89,9 +96,11 @@ function recomputePluginOrdering() { function publishRegistrationName(registrationName, pluginModule) { if (registrationNameModules[registrationName]) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); registrationNameModules[registrationName] = pluginModule; } @@ -140,7 +149,9 @@ function invokeGuardedCallbackAndCatchFirstError( caughtError = null; } else throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } @@ -158,7 +169,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; if (Array.isArray(dispatchListener)) - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null; @@ -171,7 +182,9 @@ function executeDirectDispatch(event) { function accumulateInto(current, next) { if (null == next) throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); if (null == current) return next; if (Array.isArray(current)) { @@ -208,7 +221,9 @@ var injection = { injectEventPluginOrder: function(injectedEventPluginOrder) { if (eventPluginOrder) throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); @@ -225,9 +240,11 @@ var injection = { ) { if (namesToPlugins[pluginName]) throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); namesToPlugins[pluginName] = pluginModule; isOrderingDirty = !0; @@ -269,11 +286,13 @@ function getListener(inst, registrationName) { if (inst) return null; if (listener && "function" !== typeof listener) throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); return listener; } @@ -437,7 +456,9 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { if (!(event instanceof this)) throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); event.destructor(); 10 > this.eventPool.length && this.eventPool.push(event); @@ -473,7 +494,8 @@ function timestampForTouch(touch) { } function getTouchIdentifier(_ref) { _ref = _ref.identifier; - if (null == _ref) throw ReactError("Touch object is missing identifier."); + if (null == _ref) + throw ReactError(Error("Touch object is missing identifier.")); return _ref; } function recordTouchStart(touch) { @@ -516,7 +538,7 @@ function recordTouchMove(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch move without a touch start.\nTouch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -534,7 +556,7 @@ function recordTouchEnd(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch end without a touch start.\nTouch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -588,7 +610,7 @@ var ResponderTouchHistoryStore = { function accumulate(current, next) { if (null == next) throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error("accumulate(...): Accumulated items must not be null or undefined.") ); return null == current ? next @@ -966,7 +988,9 @@ injection.injectEventPluginsByName({ directDispatchConfig = customDirectEventTypes[topLevelType]; if (!bubbleDispatchConfig && !directDispatchConfig) throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); topLevelType = SyntheticEvent.getPooled( bubbleDispatchConfig || directDispatchConfig, @@ -983,33 +1007,39 @@ injection.injectEventPluginsByName({ } } }); -var instanceCache = {}, - instanceProps = {}; +var instanceCache = new Map(), + instanceProps = new Map(); function getInstanceFromTag(tag) { - return instanceCache[tag] || null; + return instanceCache.get(tag) || null; } var restoreTarget = null, restoreQueue = null; function restoreStateOfTarget(target) { if (getInstanceFromNode(target)) throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } -function _batchedUpdatesImpl(fn, bookkeeping) { +require("../shims/ReactFeatureFlags"); +function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } -function _flushInteractiveUpdatesImpl() {} -var isBatching = !1; +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { - if (isBatching) return fn(bookkeeping); - isBatching = !0; + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - if (((isBatching = !1), null !== restoreTarget || null !== restoreQueue)) + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) if ( - (_flushInteractiveUpdatesImpl(), + (flushDiscreteUpdatesImpl(), restoreTarget && ((bookkeeping = restoreTarget), (fn = restoreQueue), @@ -1046,7 +1076,9 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); if (eventQueue) throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); if (hasRethrowError) throw ((events = rethrowError), @@ -1094,13 +1126,13 @@ ReactNativePrivateInterface.RCTEventEmitter.register({ } }); getFiberCurrentPropsFromNode = function(stateNode) { - return instanceProps[stateNode._nativeTag] || null; + return instanceProps.get(stateNode._nativeTag) || null; }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { var tag = inst.stateNode._nativeTag; void 0 === tag && (tag = inst.stateNode.canonical._nativeTag); - if (!tag) throw ReactError("All native instances should have a tag."); + if (!tag) throw ReactError(Error("All native instances should have a tag.")); return tag; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1117,6 +1149,8 @@ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher") || (ReactSharedInternals.ReactCurrentDispatcher = { current: null }); +ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig") || + (ReactSharedInternals.ReactCurrentBatchConfig = { suspense: null }); var hasSymbol = "function" === typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, @@ -1130,11 +1164,13 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, + REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; -hasSymbol && Symbol.for("react.event_component"); -hasSymbol && Symbol.for("react.event_target"); -hasSymbol && Symbol.for("react.event_target.touch_hit"); +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; @@ -1143,14 +1179,11 @@ function getIteratorFn(maybeIterable) { maybeIterable["@@iterator"]; return "function" === typeof maybeIterable ? maybeIterable : null; } -require("../shims/ReactFeatureFlags"); function getComponentName(type) { if (null == type) return null; if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -1161,6 +1194,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1195,14 +1230,14 @@ function isFiberMountedImpl(fiber) { } function assertIsMounted(fiber) { if (2 !== isFiberMountedImpl(fiber)) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; if (!alternate) { alternate = isFiberMountedImpl(fiber); if (3 === alternate) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return 1 === alternate ? null : fiber; } for (var a = fiber, b = alternate; ; ) { @@ -1223,7 +1258,7 @@ function findCurrentFiberUsingSlowPath(fiber) { if (parentB === b) return assertIsMounted(parentA), alternate; parentB = parentB.sibling; } - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } if (a.return !== b.return) (a = parentA), (b = parentB); else { @@ -1260,17 +1295,21 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (!didFindChild) throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } } if (a.alternate !== b) throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (3 !== a.tag) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return a.stateNode.current === a ? fiber : alternate; } function findCurrentHostFiber(parent) { @@ -1585,7 +1624,9 @@ var ReactNativeFiberHostComponent = (function() { })(); function shim$1() { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } var getViewConfigForType = @@ -1600,11 +1641,11 @@ function allocateTag() { } function recursivelyUncacheFiberNode(node) { if ("number" === typeof node) - delete instanceCache[node], delete instanceProps[node]; + instanceCache.delete(node), instanceProps.delete(node); else { var tag = node._nativeTag; - delete instanceCache[tag]; - delete instanceProps[tag]; + instanceCache.delete(tag); + instanceProps.delete(tag); node._children.forEach(recursivelyUncacheFiberNode); } } @@ -1620,8 +1661,22 @@ function finalizeInitialChildren(parentInstance) { return !1; } var scheduleTimeout = setTimeout, - cancelTimeout = clearTimeout, - BEFORE_SLASH_RE = /^(.*)[\\\/]/; + cancelTimeout = clearTimeout; +function removeChild(parentInstance, child) { + recursivelyUncacheFiberNode(child); + var children = parentInstance._children; + child = children.indexOf(child); + children.splice(child, 1); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, + [], + [], + [], + [], + [child] + ); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; function getStackByFiberInDevAndProd(workInProgress) { var info = ""; do { @@ -1707,7 +1762,9 @@ function popTopLevelContextObject(fiber) { function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); @@ -1720,10 +1777,12 @@ function processChildContext(fiber, type, parentContext) { for (var contextKey in instance) if (!(contextKey in fiber)) throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); return Object.assign({}, parentContext, instance); } @@ -1745,7 +1804,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { var instance = workInProgress.stateNode; if (!instance) throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); didChange ? ((type = processChildContext(workInProgress, type, previousContext)), @@ -1756,38 +1817,11 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -var onCommitFiberRoot = null, - onCommitFiberUnmount = null; -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) {} - }; -} -function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - var rendererID = hook.inject(internals); - onCommitFiberRoot = catchErrors(function(root) { - hook.onCommitFiberRoot( - rendererID, - root, - void 0, - 64 === (root.current.effectTag & 64) - ); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) {} - return !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 = Scheduler.unstable_now, Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel, @@ -1797,10 +1831,11 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_LowPriority = Scheduler.unstable_LowPriority, Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, fakeCallbackNode = {}, - shouldYield = Scheduler.unstable_shouldYield, - immediateQueue = null, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, immediateQueueCallbackNode = null, - isFlushingImmediate = !1, + isFlushingSyncQueue = !1, initialTimeMs = Scheduler_now(), now = 1e4 > initialTimeMs @@ -1821,7 +1856,7 @@ function getCurrentPriorityLevel() { case Scheduler_IdlePriority: return 95; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function reactPriorityToSchedulerPriority(reactPriorityLevel) { @@ -1837,7 +1872,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case 95: return Scheduler_IdlePriority; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function runWithPriority(reactPriorityLevel, fn) { @@ -1845,46 +1880,47 @@ function runWithPriority(reactPriorityLevel, fn) { return Scheduler_runWithPriority(reactPriorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (99 === reactPriorityLevel) - return ( - null === immediateQueue - ? ((immediateQueue = [callback]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ))) - : immediateQueue.push(callback), - fakeCallbackNode - ); reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function flushImmediateQueue() { +function scheduleSyncCallback(callback) { + null === syncQueue + ? ((syncQueue = [callback]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(callback); + return fakeCallbackNode; +} +function flushSyncCallbackQueue() { null !== immediateQueueCallbackNode && Scheduler_cancelCallback(immediateQueueCallbackNode); - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && null !== immediateQueue) { - isFlushingImmediate = !0; +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; var i = 0; try { - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do callback = callback(!0); - while (null !== callback); - } - immediateQueue = null; + 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 !== immediateQueue && - (immediateQueue = immediateQueue.slice(i + 1)), + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ), error); } finally { - isFlushingImmediate = !1; + isFlushingSyncQueue = !1; } } } @@ -1892,7 +1928,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (1073741823 === expirationTime) return 99; if (1 === expirationTime) return 95; currentTime = - 10 * (1073741822 - expirationTime) - 10 * (1073741822 - currentTime); + 10 * (1073741821 - expirationTime) - 10 * (1073741821 - currentTime); return 0 >= currentTime ? 99 : 250 >= currentTime @@ -1974,7 +2010,7 @@ var valueCursor = { current: null }, currentlyRenderingFiber = null, lastContextDependency = null, lastContextWithAllBitsObserved = null; -function resetContextDependences() { +function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } function pushProvider(providerFiber, nextValue) { @@ -1987,14 +2023,32 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); providerFiber.type._context._currentValue = currentValue; } +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + for (; null !== parent; ) { + var alternate = parent.alternate; + if (parent.childExpirationTime < renderExpirationTime) + (parent.childExpirationTime = renderExpirationTime), + null !== alternate && + alternate.childExpirationTime < renderExpirationTime && + (alternate.childExpirationTime = renderExpirationTime); + else if ( + null !== alternate && + alternate.childExpirationTime < renderExpirationTime + ) + alternate.childExpirationTime = renderExpirationTime; + else break; + parent = parent.return; + } +} function prepareToReadContext(workInProgress, renderExpirationTime) { currentlyRenderingFiber = workInProgress; lastContextWithAllBitsObserved = lastContextDependency = null; - var currentDependencies = workInProgress.contextDependencies; - null !== currentDependencies && - currentDependencies.expirationTime >= renderExpirationTime && - (didReceiveUpdate = !0); - workInProgress.contextDependencies = null; + workInProgress = workInProgress.dependencies; + null !== workInProgress && + null !== workInProgress.firstContext && + (workInProgress.expirationTime >= renderExpirationTime && + (didReceiveUpdate = !0), + (workInProgress.firstContext = null)); } function readContext(context, observedBits) { if ( @@ -2008,12 +2062,16 @@ function readContext(context, observedBits) { if (null === lastContextDependency) { if (null === currentlyRenderingFiber) throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); lastContextDependency = observedBits; - currentlyRenderingFiber.contextDependencies = { - first: observedBits, - expirationTime: 0 + currentlyRenderingFiber.dependencies = { + expirationTime: 0, + firstContext: observedBits, + listeners: null, + responders: null }; } else lastContextDependency = lastContextDependency.next = observedBits; } @@ -2046,9 +2104,10 @@ function cloneUpdateQueue(currentQueue) { lastCapturedEffect: null }; } -function createUpdate(expirationTime) { +function createUpdate(expirationTime, suspenseConfig) { return { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, @@ -2164,8 +2223,10 @@ function processUpdateQueue( ((newFirstUpdate = update), (newBaseState = resultState)), newExpirationTime < updateExpirationTime && (newExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), (resultState = getStateFromUpdate( workInProgress, queue, @@ -2241,15 +2302,18 @@ function commitUpdateEffects(effect, instance) { var context = instance; if ("function" !== typeof _callback3) throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - _callback3 + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + _callback3 + ) ); _callback3.call(context); } effect = effect.nextEffect; } } -var emptyRefsObject = new React.Component().refs; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + emptyRefsObject = new React.Component().refs; function applyDerivedStateFromProps( workInProgress, ctor, @@ -2276,36 +2340,42 @@ var classComponentUpdater = { }, enqueueSetState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 1; + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 2; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 2; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); } }; @@ -2434,15 +2504,19 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); inst = element.stateNode; } if (!inst) throw ReactError( - "Missing owner for string ref " + - returnFiber + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + returnFiber + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); var stringRef = "" + returnFiber; if ( @@ -2462,13 +2536,17 @@ function coerceRef(returnFiber, current$$1, element) { } if ("string" !== typeof returnFiber) throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); if (!element._owner) throw ReactError( - "Element ref was specified as a string (" + - returnFiber + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + returnFiber + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } return returnFiber; @@ -2476,11 +2554,13 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) throw ReactError( - "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === Object.prototype.toString.call(newChild) + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + ) ); } function ChildReconciler(shouldTrackSideEffects) { @@ -2883,11 +2963,13 @@ function ChildReconciler(shouldTrackSideEffects) { var iteratorFn = getIteratorFn(newChildrenIterable); if ("function" !== typeof iteratorFn) throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); newChildrenIterable = iteratorFn.call(newChildrenIterable); if (null == newChildrenIterable) - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); for ( var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, @@ -3122,8 +3204,10 @@ function ChildReconciler(shouldTrackSideEffects) { case 0: throw ((returnFiber = returnFiber.type), ReactError( - (returnFiber.displayName || returnFiber.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (returnFiber.displayName || returnFiber.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) )); } return deleteRemainingChildren(returnFiber, currentFirstChild); @@ -3138,7 +3222,9 @@ var reconcileChildFibers = ChildReconciler(!0), function requiredContext(c) { if (c === NO_CONTEXT) throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); return c; } @@ -3176,6 +3262,50 @@ function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } +var SubtreeSuspenseContextMask = 1, + InvisibleParentSuspenseContext = 1, + ForceSuspenseFallback = 2, + suspenseStackCursor = { current: 0 }; +function findFirstSuspended(row) { + for (var node = row; null !== node; ) { + if (13 === node.tag) { + if (null !== node.memoizedState) return node; + } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { + if (0 !== (node.effectTag & 64)) return node; + } else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; +} +var currentListenerHookIndex = 0; +function updateListenerHook(responder, props) { + var dependencies = null.dependencies; + null === dependencies && + (dependencies = null.dependencies = { + expirationTime: 0, + firstContext: null, + listeners: [], + responders: null + }); + var listeners = dependencies.listeners; + null === listeners && (dependencies.listeners = listeners = []); + listeners.length === currentListenerHookIndex + ? (listeners.push({ responder: responder, props: props }), + currentListenerHookIndex++) + : ((listeners = listeners[currentListenerHookIndex++]), + (listeners.responder = responder), + (listeners.props = props)); +} var NoEffect$1 = 0, UnmountSnapshot = 2, UnmountMutation = 4, @@ -3200,7 +3330,9 @@ var NoEffect$1 = 0, numberOfReRenders = 0; function throwInvalidHookError() { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } function areHookInputsEqual(nextDeps, prevDeps) { @@ -3250,7 +3382,9 @@ function renderWithHooks( sideEffectTag = 0; if (current) throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); return workInProgress; } @@ -3286,7 +3420,9 @@ function updateWorkInProgressHook() { (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) - throw ReactError("Rendered more hooks than during the previous render."); + throw ReactError( + Error("Rendered more hooks than during the previous render.") + ); currentHook = nextCurrentHook; var newHook = { memoizedState: currentHook.memoizedState, @@ -3311,7 +3447,9 @@ function updateReducer(reducer) { queue = hook.queue; if (null === queue) throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); queue.lastRenderedReducer = reducer; if (0 < numberOfReRenders) { @@ -3354,8 +3492,10 @@ function updateReducer(reducer) { (firstRenderPhaseUpdate = newState)), updateExpirationTime > remainingExpirationTime && (remainingExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ), (newState = _update.eagerReducer === reducer ? _update.eagerState @@ -3434,7 +3574,9 @@ function mountDebugValue() {} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); var alternate = fiber.alternate; if ( @@ -3445,6 +3587,7 @@ function dispatchAction(fiber, queue, action) { ((didScheduleRenderPhaseUpdate = !0), (fiber = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, @@ -3460,24 +3603,29 @@ function dispatchAction(fiber, queue, action) { queue.next = fiber; } else { - flushPassiveEffects(); - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, fiber); - var _update2 = { - expirationTime: currentTime, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }, - _last = queue.last; - if (null === _last) _update2.next = _update2; + var currentTime = requestCurrentTime(), + _suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); + _suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: _suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var _last = queue.last; + if (null === _last) _suspenseConfig.next = _suspenseConfig; else { var first = _last.next; - null !== first && (_update2.next = first); - _last.next = _update2; + null !== first && (_suspenseConfig.next = first); + _last.next = _suspenseConfig; } - queue.last = _update2; + queue.last = _suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3486,8 +3634,8 @@ function dispatchAction(fiber, queue, action) { try { var currentState = queue.lastRenderedState, _eagerState = alternate(currentState, action); - _update2.eagerReducer = alternate; - _update2.eagerState = _eagerState; + _suspenseConfig.eagerReducer = alternate; + _suspenseConfig.eagerState = _eagerState; if (is(_eagerState, currentState)) return; } catch (error) { } finally { @@ -3506,7 +3654,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3579,7 +3728,8 @@ var ContextOnlyDispatcher = { ); return [hook.memoizedState, initialState]; }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, HooksDispatcherOnUpdate = { readContext: readContext, @@ -3633,7 +3783,8 @@ var ContextOnlyDispatcher = { useState: function(initialState) { return updateReducer(basicStateReducer, initialState); }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, hydrationParentFiber = null, nextHydratableInstance = null, @@ -4174,6 +4325,7 @@ function pushHostRootContext(workInProgress) { pushTopLevelContextObject(workInProgress, root.context, !1); pushHostContainer(workInProgress, root.containerInfo); } +var SUSPENDED_MARKER = {}; function updateSuspenseComponent( current$$1, workInProgress, @@ -4181,100 +4333,271 @@ function updateSuspenseComponent( ) { var mode = workInProgress.mode, nextProps = workInProgress.pendingProps, - nextState = workInProgress.memoizedState; - if (0 === (workInProgress.effectTag & 64)) { - nextState = null; - var nextDidTimeout = !1; - } else - (nextState = { - fallbackExpirationTime: - null !== nextState ? nextState.fallbackExpirationTime : 0 - }), + suspenseContext = suspenseStackCursor.current, + nextState = null, + nextDidTimeout = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || + (JSCompiler_temp = + 0 !== (suspenseContext & ForceSuspenseFallback) && + (null === current$$1 || null !== current$$1.memoizedState)); + JSCompiler_temp + ? ((nextState = SUSPENDED_MARKER), (nextDidTimeout = !0), - (workInProgress.effectTag &= -65); + (workInProgress.effectTag &= -65)) + : (null !== current$$1 && null === current$$1.memoizedState) || + void 0 === nextProps.fallback || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= InvisibleParentSuspenseContext); + suspenseContext &= SubtreeSuspenseContextMask; + push(suspenseStackCursor, suspenseContext, workInProgress); if (null === current$$1) if (nextDidTimeout) { - var nextFallbackChildren = nextProps.fallback; + nextProps = nextProps.fallback; current$$1 = createFiberFromFragment(null, mode, 0, null); - 0 === (workInProgress.mode & 1) && - (current$$1.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child); - mode = createFiberFromFragment( - nextFallbackChildren, + current$$1.return = workInProgress; + if (0 === (workInProgress.mode & 2)) + for ( + nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + current$$1.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = current$$1), + (nextDidTimeout = nextDidTimeout.sibling); + renderExpirationTime = createFiberFromFragment( + nextProps, mode, renderExpirationTime, null ); - current$$1.sibling = mode; - renderExpirationTime = current$$1; - renderExpirationTime.return = mode.return = workInProgress; + renderExpirationTime.return = workInProgress; + current$$1.sibling = renderExpirationTime; + mode = current$$1; } else - renderExpirationTime = mode = mountChildFibers( + mode = renderExpirationTime = mountChildFibers( workInProgress, null, nextProps.children, renderExpirationTime ); - else - null !== current$$1.memoizedState - ? ((mode = current$$1.child), - (nextFallbackChildren = mode.sibling), - nextDidTimeout - ? ((renderExpirationTime = nextProps.fallback), - (nextProps = createWorkInProgress(mode, mode.pendingProps, 0)), - 0 === (workInProgress.mode & 1) && - ((nextDidTimeout = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child), - nextDidTimeout !== mode.child && - (nextProps.child = nextDidTimeout)), - (mode = nextProps.sibling = createWorkInProgress( - nextFallbackChildren, - renderExpirationTime, - nextFallbackChildren.expirationTime - )), - (renderExpirationTime = nextProps), - (nextProps.childExpirationTime = 0), - (renderExpirationTime.return = mode.return = workInProgress)) - : (renderExpirationTime = mode = reconcileChildFibers( - workInProgress, - mode.child, - nextProps.children, - renderExpirationTime - ))) - : ((nextFallbackChildren = current$$1.child), - nextDidTimeout - ? ((nextDidTimeout = nextProps.fallback), - (nextProps = createFiberFromFragment(null, mode, 0, null)), - (nextProps.child = nextFallbackChildren), - 0 === (workInProgress.mode & 1) && - (nextProps.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child), - (mode = nextProps.sibling = createFiberFromFragment( - nextDidTimeout, - mode, - renderExpirationTime, - null - )), - (mode.effectTag |= 2), - (renderExpirationTime = nextProps), - (nextProps.childExpirationTime = 0), - (renderExpirationTime.return = mode.return = workInProgress)) - : (mode = renderExpirationTime = reconcileChildFibers( - workInProgress, - nextFallbackChildren, - nextProps.children, - renderExpirationTime - ))), - (workInProgress.stateNode = current$$1.stateNode); + else { + if (null !== current$$1.memoizedState) + if ( + ((suspenseContext = current$$1.child), + (mode = suspenseContext.sibling), + nextDidTimeout) + ) { + nextProps = nextProps.fallback; + renderExpirationTime = createWorkInProgress( + suspenseContext, + suspenseContext.pendingProps, + 0 + ); + renderExpirationTime.return = workInProgress; + if ( + 0 === (workInProgress.mode & 2) && + ((nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child), + nextDidTimeout !== suspenseContext.child) + ) + for ( + renderExpirationTime.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = renderExpirationTime), + (nextDidTimeout = nextDidTimeout.sibling); + nextProps = createWorkInProgress(mode, nextProps, mode.expirationTime); + nextProps.return = workInProgress; + renderExpirationTime.sibling = nextProps; + mode = renderExpirationTime; + renderExpirationTime.childExpirationTime = 0; + renderExpirationTime = nextProps; + } else + mode = renderExpirationTime = reconcileChildFibers( + workInProgress, + suspenseContext.child, + nextProps.children, + renderExpirationTime + ); + else if (((suspenseContext = current$$1.child), nextDidTimeout)) { + nextDidTimeout = nextProps.fallback; + nextProps = createFiberFromFragment(null, mode, 0, null); + nextProps.return = workInProgress; + nextProps.child = suspenseContext; + null !== suspenseContext && (suspenseContext.return = nextProps); + if (0 === (workInProgress.mode & 2)) + for ( + suspenseContext = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + nextProps.child = suspenseContext; + null !== suspenseContext; + + ) + (suspenseContext.return = nextProps), + (suspenseContext = suspenseContext.sibling); + renderExpirationTime = createFiberFromFragment( + nextDidTimeout, + mode, + renderExpirationTime, + null + ); + renderExpirationTime.return = workInProgress; + nextProps.sibling = renderExpirationTime; + renderExpirationTime.effectTag |= 2; + mode = nextProps; + nextProps.childExpirationTime = 0; + } else + renderExpirationTime = mode = reconcileChildFibers( + workInProgress, + suspenseContext, + nextProps.children, + renderExpirationTime + ); + workInProgress.stateNode = current$$1.stateNode; + } workInProgress.memoizedState = nextState; - workInProgress.child = renderExpirationTime; - return mode; + workInProgress.child = mode; + return renderExpirationTime; +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailExpiration = 0), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren( + current$$1, + workInProgress, + nextProps.children, + renderExpirationTime + ); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & ForceSuspenseFallback)) + (nextProps = + (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), + (workInProgress.effectTag |= 64); + else { + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) { + if (null !== current$$1.memoizedState) { + current$$1.expirationTime < renderExpirationTime && + (current$$1.expirationTime = renderExpirationTime); + var alternate = current$$1.alternate; + null !== alternate && + alternate.expirationTime < renderExpirationTime && + (alternate.expirationTime = renderExpirationTime); + scheduleWorkOnParentPath(current$$1.return, renderExpirationTime); + } + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) + break a; + current$$1 = current$$1.return; + } + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + nextProps &= SubtreeSuspenseContextMask; + } + push(suspenseStackCursor, nextProps, workInProgress); + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderExpirationTime = workInProgress.child; + for (revealOrder = null; null !== renderExpirationTime; ) + (nextProps = renderExpirationTime.alternate), + null !== nextProps && + null === findFirstSuspended(nextProps) && + (revealOrder = renderExpirationTime), + (renderExpirationTime = renderExpirationTime.sibling); + renderExpirationTime = revealOrder; + null === renderExpirationTime + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderExpirationTime.sibling), + (renderExpirationTime.sibling = null)); + initSuspenseListRenderState( + workInProgress, + !1, + revealOrder, + renderExpirationTime, + tailMode + ); + break; + case "backwards": + renderExpirationTime = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + nextProps = revealOrder.alternate; + if (null !== nextProps && null === findFirstSuspended(nextProps)) { + workInProgress.child = revealOrder; + break; + } + nextProps = revealOrder.sibling; + revealOrder.sibling = renderExpirationTime; + renderExpirationTime = revealOrder; + revealOrder = nextProps; + } + initSuspenseListRenderState( + workInProgress, + !0, + renderExpirationTime, + null, + tailMode + ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; + } + return workInProgress.child; } function bailoutOnAlreadyFinishedWork( current$$1, @@ -4282,10 +4605,10 @@ function bailoutOnAlreadyFinishedWork( renderExpirationTime ) { null !== current$$1 && - (workInProgress.contextDependencies = current$$1.contextDependencies); + (workInProgress.dependencies = current$$1.dependencies); if (workInProgress.childExpirationTime < renderExpirationTime) return null; if (null !== current$$1 && workInProgress.child !== current$$1.child) - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); if (null !== workInProgress.child) { current$$1 = workInProgress.child; renderExpirationTime = createWorkInProgress( @@ -4317,6 +4640,7 @@ var appendAllChildren = void 0, appendAllChildren = function(parent, workInProgress) { for (var node = workInProgress.child; null !== node; ) { if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); + else if (20 === node.tag) parent._children.push(node.stateNode.instance); else if (4 !== node.tag && null !== node.child) { node.child.return = node; node = node.child; @@ -4341,6 +4665,74 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { updateHostText$1 = function(current, workInProgress, oldText, newText) { oldText !== newText && (workInProgress.effectTag |= 4); }; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var _lastTailNode = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === _lastTailNode + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (_lastTailNode.sibling = null); + } +} +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + workInProgress.effectTag = (effectTag & -2049) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null + ); + case 18: + return null; + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} function createCapturedValue(value, source) { return { value: value, @@ -4348,24 +4740,18 @@ function createCapturedValue(value, source) { stack: getStackByFiberInDevAndProd(source) }; } +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") + ); function logCapturedError(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - if (error instanceof Error) { - capturedError = error.message; - var name = error.name; - try { - error.message = - (capturedError ? name + ": " + capturedError : name) + - "\n\nThis error is located at:" + - componentStack; - } catch (e) {} - } else - error = - "string" === typeof error - ? Error(error + "\n\nThis error is located at:" + componentStack) - : Error("Unspecified error at:" + componentStack); - ReactNativePrivateInterface.ExceptionsManager.handleException(error, !1); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ) && console.error(capturedError.error); } var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; function logError(boundary, errorInfo) { @@ -4425,64 +4811,6 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } -function hideOrUnhideAllChildren(finishedWork, isHidden) { - for (var node = finishedWork; ; ) { - if (5 === node.tag) { - var instance = node.stateNode; - if (isHidden) { - var viewConfig = instance.viewConfig; - var updatePayload = diffProperties( - null, - emptyObject, - { style: { display: "none" } }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } else { - instance = node.stateNode; - updatePayload = node.memoizedProps; - viewConfig = instance.viewConfig; - var prevProps = Object.assign({}, updatePayload, { - style: [updatePayload.style, { display: "none" }] - }); - updatePayload = diffProperties( - null, - prevProps, - updatePayload, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } - } else { - if (6 === node.tag) throw Error("Not yet implemented."); - if (13 === node.tag && null !== node.memoizedState) { - instance = node.child.sibling; - instance.return = node; - node = instance; - continue; - } else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - } - if (node === finishedWork) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === finishedWork) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -} function commitUnmount(current$$1$jscomp$0) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -4530,6 +4858,20 @@ function commitUnmount(current$$1$jscomp$0) { unmountHostComponents(current$$1$jscomp$0); } } +function commitNestedUnmounts(root) { + for (var node = root; ; ) + if ((commitUnmount(node), null !== node.child && 4 !== node.tag)) + (node.child.return = node), (node = node.child); + else { + if (node === root) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === root) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} function isHostParent(fiber) { return 5 === fiber.tag || 3 === fiber.tag || 4 === fiber.tag; } @@ -4543,25 +4885,29 @@ function commitPlacement(finishedWork) { parent = parent.return; } throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } + parent = parentFiber.stateNode; switch (parentFiber.tag) { case 5: - parent = parentFiber.stateNode; var isContainer = !1; break; case 3: - parent = parentFiber.stateNode.containerInfo; + parent = parent.containerInfo; isContainer = !0; break; case 4: - parent = parentFiber.stateNode.containerInfo; + parent = parent.containerInfo; isContainer = !0; break; default: throw ReactError( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ) ); } parentFiber.effectTag & 16 && (parentFiber.effectTag &= -17); @@ -4591,25 +4937,26 @@ function commitPlacement(finishedWork) { } } for (var node = finishedWork; ; ) { - if (5 === node.tag || 6 === node.tag) { - var stateNode = node.stateNode; + var isHost = 5 === node.tag || 6 === node.tag; + if (isHost || 20 === node.tag) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; if (parentFiber) if (isContainer) { if ("number" === typeof parent) throw ReactError( - "Container does not support insertBefore operation" + Error("Container does not support insertBefore operation") ); } else { - var parentInstance = parent, - beforeChild = parentFiber, - children = parentInstance._children, + isHost = parent; + var beforeChild = parentFiber, + children = isHost._children, index = children.indexOf(stateNode); 0 <= index ? (children.splice(index, 1), (beforeChild = children.indexOf(beforeChild)), children.splice(beforeChild, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [index], [beforeChild], [], @@ -4619,7 +4966,7 @@ function commitPlacement(finishedWork) { : ((index = children.indexOf(beforeChild)), children.splice(index, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [], [], [ @@ -4636,16 +4983,16 @@ function commitPlacement(finishedWork) { ? ReactNativePrivateInterface.UIManager.setChildren(parent, [ "number" === typeof stateNode ? stateNode : stateNode._nativeTag ]) - : ((parentInstance = parent), + : ((isHost = parent), (children = "number" === typeof stateNode ? stateNode : stateNode._nativeTag), - (index = parentInstance._children), + (index = isHost._children), (beforeChild = index.indexOf(stateNode)), 0 <= beforeChild ? (index.splice(beforeChild, 1), index.push(stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [beforeChild], [index.length - 1], [], @@ -4654,7 +5001,7 @@ function commitPlacement(finishedWork) { )) : (index.push(stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [], [], [children], @@ -4689,19 +5036,21 @@ function unmountHostComponents(current$$1) { a: for (;;) { if (null === currentParentIsValid) throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); + currentParent = currentParentIsValid.stateNode; switch (currentParentIsValid.tag) { case 5: - currentParent = currentParentIsValid.stateNode; currentParentIsContainer = !1; break a; case 3: - currentParent = currentParentIsValid.stateNode.containerInfo; + currentParent = currentParent.containerInfo; currentParentIsContainer = !0; break a; case 4: - currentParent = currentParentIsValid.stateNode.containerInfo; + currentParent = currentParent.containerInfo; currentParentIsContainer = !0; break a; } @@ -4709,52 +5058,37 @@ function unmountHostComponents(current$$1) { } currentParentIsValid = !0; } - if (5 === node.tag || 6 === node.tag) { - a: for (var root = node, node$jscomp$0 = root; ; ) - if ( - (commitUnmount(node$jscomp$0), - null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) - ) - (node$jscomp$0.child.return = node$jscomp$0), - (node$jscomp$0 = node$jscomp$0.child); - else { - if (node$jscomp$0 === root) break; - for (; null === node$jscomp$0.sibling; ) { - if (null === node$jscomp$0.return || node$jscomp$0.return === root) - break a; - node$jscomp$0 = node$jscomp$0.return; - } - node$jscomp$0.sibling.return = node$jscomp$0.return; - node$jscomp$0 = node$jscomp$0.sibling; - } - if (currentParentIsContainer) - (root = currentParent), - recursivelyUncacheFiberNode(node.stateNode), - ReactNativePrivateInterface.UIManager.manageChildren( - root, - [], - [], - [], - [], - [0] - ); - else { - root = currentParent; - var child = node.stateNode; - recursivelyUncacheFiberNode(child); - node$jscomp$0 = root._children; - child = node$jscomp$0.indexOf(child); - node$jscomp$0.splice(child, 1); + if (5 === node.tag || 6 === node.tag) + if ((commitNestedUnmounts(node), currentParentIsContainer)) { + var parentInstance = currentParent; + recursivelyUncacheFiberNode(node.stateNode); ReactNativePrivateInterface.UIManager.manageChildren( - root._nativeTag, + parentInstance, [], [], [], [], - [child] + [0] ); - } - } else if (4 === node.tag) { + } else removeChild(currentParent, node.stateNode); + else if (20 === node.tag) + if ( + ((parentInstance = node.stateNode.instance), + commitNestedUnmounts(node), + currentParentIsContainer) + ) { + var parentInstance$jscomp$0 = currentParent; + recursivelyUncacheFiberNode(parentInstance); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance$jscomp$0, + [], + [], + [], + [], + [0] + ); + } else removeChild(currentParent, parentInstance); + else if (4 === node.tag) { if (null !== node.child) { currentParent = node.stateNode.containerInfo; currentParentIsContainer = !0; @@ -4796,7 +5130,7 @@ function commitWork(current$$1, finishedWork) { finishedWork.updateQueue = null; null !== updatePayload && ((finishedWork = instance.viewConfig), - (instanceProps[instance._nativeTag] = newProps), + instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, current$$1, @@ -4814,7 +5148,9 @@ function commitWork(current$$1, finishedWork) { case 6: if (null === finishedWork.stateNode) throw ReactError( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ) ); ReactNativePrivateInterface.UIManager.updateView( finishedWork.stateNode, @@ -4822,44 +5158,99 @@ function commitWork(current$$1, finishedWork) { { text: finishedWork.memoizedProps } ); break; - case 20: - break; case 3: break; case 12: break; case 13: - commitSuspenseComponent(finishedWork); + instance = finishedWork; + null === finishedWork.memoizedState + ? (newProps = !1) + : ((newProps = !0), + (instance = finishedWork.child), + (globalMostRecentFallbackTime = now())); + if (null !== instance) + a: for (current$$1 = instance; ; ) { + if (5 === current$$1.tag) + if (((updatePayload = current$$1.stateNode), newProps)) { + var viewConfig = updatePayload.viewConfig; + var updatePayload$jscomp$0 = diffProperties( + null, + emptyObject, + { style: { display: "none" } }, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } else { + updatePayload = current$$1.stateNode; + updatePayload$jscomp$0 = current$$1.memoizedProps; + viewConfig = updatePayload.viewConfig; + var prevProps = Object.assign({}, updatePayload$jscomp$0, { + style: [updatePayload$jscomp$0.style, { display: "none" }] + }); + updatePayload$jscomp$0 = diffProperties( + null, + prevProps, + updatePayload$jscomp$0, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } + else { + if (6 === current$$1.tag) throw Error("Not yet implemented."); + if (13 === current$$1.tag && null !== current$$1.memoizedState) { + updatePayload = current$$1.child.sibling; + updatePayload.return = current$$1; + current$$1 = updatePayload; + continue; + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + } + if (current$$1 === instance) break a; + for (; null === current$$1.sibling; ) { + if (null === current$$1.return || current$$1.return === instance) + break a; + current$$1 = current$$1.return; + } + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + attachSuspenseRetryListeners(finishedWork); + break; + case 19: + attachSuspenseRetryListeners(finishedWork); break; case 17: break; - case 19: + case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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 commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState, - newDidTimeout = void 0, - primaryChildParent = finishedWork; - null === newState - ? (newDidTimeout = !1) - : ((newDidTimeout = !0), - (primaryChildParent = finishedWork.child), - 0 === newState.fallbackExpirationTime && - (newState.fallbackExpirationTime = requestCurrentTime() - 500)); - null !== primaryChildParent && - hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); - newState = finishedWork.updateQueue; - if (null !== newState) { +function attachSuspenseRetryListeners(finishedWork) { + var thenables = finishedWork.updateQueue; + if (null !== thenables) { finishedWork.updateQueue = null; var retryCache = finishedWork.stateNode; null === retryCache && (retryCache = finishedWork.stateNode = new PossiblyWeakSet$1()); - newState.forEach(function(thenable) { + thenables.forEach(function(thenable) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); retryCache.has(thenable) || (retryCache.add(thenable), thenable.then(retry, retry)); @@ -4868,7 +5259,7 @@ function commitSuspenseComponent(finishedWork) { } var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; expirationTime.payload = { element: null }; var error = errorInfo.value; @@ -4879,7 +5270,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { @@ -4905,64 +5296,29 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { }); return expirationTime; } -function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null; - case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -2049) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: - return ( - (effectTag = workInProgress.effectTag), - effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null - ); - case 18: - return null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 19: - case 20: - return null; - default: - return null; - } -} var ceil = Math.ceil, ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - LegacyUnbatchedPhase = 2, - RenderPhase = 4, - CommitPhase = 5, + NoContext = 0, + LegacyUnbatchedContext = 8, + RenderContext = 16, + CommitContext = 32, RootIncomplete = 0, RootErrored = 1, RootSuspended = 2, - RootCompleted = 3, - workPhase = 0, + RootSuspendedWithDelay = 3, + RootCompleted = 4, + executionContext = NoContext, workInProgressRoot = null, workInProgress = null, renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, - workInProgressRootMostRecentEventTime = 1073741823, + workInProgressRootLatestProcessedExpirationTime = 1073741823, + workInProgressRootLatestSuspenseTimeout = 1073741823, + workInProgressRootCanSuspendUsingConfig = null, + workInProgressRootHasPendingPing = !1, + globalMostRecentFallbackTime = 0, + FALLBACK_THROTTLE_MS = 500, nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, @@ -4974,34 +5330,49 @@ var ceil = Math.ceil, rootWithNestedUpdates = null, currentEventTime = 0; function requestCurrentTime() { - return workPhase === RenderPhase || workPhase === CommitPhase - ? 1073741822 - ((now() / 10) | 0) + return (executionContext & (RenderContext | CommitContext)) !== NoContext + ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime ? currentEventTime - : (currentEventTime = 1073741822 - ((now() / 10) | 0)); -} -function computeExpirationForFiber(currentTime, fiber) { - if (0 === (fiber.mode & 1)) return 1073741823; - if (workPhase === RenderPhase) return renderExpirationTime; - switch (getCurrentPriorityLevel()) { - case 99: - currentTime = 1073741823; - break; - case 98: - currentTime = - 1073741822 - 10 * ((((1073741822 - currentTime + 15) / 10) | 0) + 1); - break; - case 97: - case 96: - currentTime = - 1073741822 - 25 * ((((1073741822 - currentTime + 500) / 25) | 0) + 1); - break; - case 95: - currentTime = 1; - break; - default: - throw ReactError("Expected a valid priority level"); - } + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); +} +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + fiber = fiber.mode; + if (0 === (fiber & 2)) return 1073741823; + var priorityLevel = getCurrentPriorityLevel(); + if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; + if ((executionContext & RenderContext) !== NoContext) + return renderExpirationTime; + if (null !== suspenseConfig) + currentTime = + 1073741821 - + 25 * + ((((1073741821 - + currentTime + + (suspenseConfig.timeoutMs | 0 || 5e3) / 10) / + 25) | + 0) + + 1); + else + switch (priorityLevel) { + case 99: + currentTime = 1073741823; + break; + case 98: + currentTime = + 1073741821 - 10 * ((((1073741821 - currentTime + 15) / 10) | 0) + 1); + break; + case 97: + case 96: + currentTime = + 1073741821 - 25 * ((((1073741821 - currentTime + 500) / 25) | 0) + 1); + break; + case 95: + currentTime = 1; + break; + default: + throw ReactError(Error("Expected a valid priority level")); + } null !== workInProgressRoot && currentTime === renderExpirationTime && --currentTime; @@ -5012,33 +5383,37 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) )); fiber = markUpdateTimeFromFiberToRoot(fiber, expirationTime); - if (null !== fiber) - if (((fiber.pingTime = 0), 1073741823 === expirationTime)) - if (workPhase === LegacyUnbatchedPhase) + if (null !== fiber) { + fiber.pingTime = 0; + var priorityLevel = getCurrentPriorityLevel(); + if (1073741823 === expirationTime) + if ( + (executionContext & LegacyUnbatchedContext) !== NoContext && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) for ( - expirationTime = renderRoot(fiber, 1073741823, !0); - null !== expirationTime; + var callback = renderRoot(fiber, 1073741823, !0); + null !== callback; ) - expirationTime = expirationTime(!0); + callback = callback(!0); else scheduleCallbackForRoot(fiber, 99, 1073741823), - 0 === workPhase && flushImmediateQueue(); - else { - var priorityLevel = getCurrentPriorityLevel(); - if (98 === priorityLevel) - if (null === rootsWithPendingDiscreteUpdates) - rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]]); - else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(fiber); - (void 0 === lastDiscreteTime || lastDiscreteTime > expirationTime) && - rootsWithPendingDiscreteUpdates.set(fiber, expirationTime); - } - scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); - } + executionContext === NoContext && flushSyncCallbackQueue(); + else scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); + (executionContext & 4) === NoContext || + (98 !== priorityLevel && 99 !== priorityLevel) || + (null === rootsWithPendingDiscreteUpdates + ? (rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]])) + : ((priorityLevel = rootsWithPendingDiscreteUpdates.get(fiber)), + (void 0 === priorityLevel || priorityLevel > expirationTime) && + rootsWithPendingDiscreteUpdates.set(fiber, expirationTime))); + } } function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { fiber.expirationTime < expirationTime && @@ -5079,21 +5454,28 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode); root.callbackExpirationTime = expirationTime; - existingCallbackNode = null; - 1073741823 !== expirationTime && - 1 !== expirationTime && - ((existingCallbackNode = 10 * (1073741822 - expirationTime) - now()), - 5e3 < existingCallbackNode && (existingCallbackNode = 5e3), - (existingCallbackNode = { timeout: existingCallbackNode })); - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - existingCallbackNode - ); + 1073741823 === expirationTime + ? (root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + )) + : ((existingCallbackNode = null), + 1 !== expirationTime && + (existingCallbackNode = { + timeout: 10 * (1073741821 - expirationTime) - now() + }), + (root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + existingCallbackNode + ))); } } function runRootCallback(root, callback, isSync) { @@ -5117,9 +5499,7 @@ function resolveLocksOnRoot(root, expirationTime) { return null !== firstBatch && firstBatch._defer && firstBatch._expirationTime >= expirationTime - ? ((root.finishedWork = root.current.alternate), - (root.pendingCommitExpirationTime = expirationTime), - scheduleCallback(97, function() { + ? (scheduleCallback(97, function() { firstBatch._onComplete(); return null; }), @@ -5131,13 +5511,14 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback(99, renderRoot.bind(null, root, expirationTime)); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = 0; + root.finishedWork = null; + root.finishedExpirationTime = 0; var timeoutHandle = root.timeoutHandle; -1 !== timeoutHandle && ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); @@ -5161,6 +5542,12 @@ function prepareFreshStack(root, expirationTime) { case 4: popHostContainer(interruptedWork); break; + case 13: + pop(suspenseStackCursor, interruptedWork); + break; + case 19: + pop(suspenseStackCursor, interruptedWork); + break; case 10: popProvider(interruptedWork); } @@ -5170,24 +5557,33 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = 1073741823; + workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = !1; } function renderRoot(root$jscomp$0, expirationTime, isSync) { - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); if (root$jscomp$0.firstPendingTime < expirationTime) return null; - if (root$jscomp$0.pendingCommitExpirationTime === expirationTime) - return ( - (root$jscomp$0.pendingCommitExpirationTime = 0), - commitRoot.bind(null, root$jscomp$0, expirationTime) - ); + if (isSync && root$jscomp$0.finishedExpirationTime === expirationTime) + return commitRoot.bind(null, root$jscomp$0); flushPassiveEffects(); - (root$jscomp$0 === workInProgressRoot && - expirationTime === renderExpirationTime) || + if ( + root$jscomp$0 !== workInProgressRoot || + expirationTime !== renderExpirationTime + ) prepareFreshStack(root$jscomp$0, expirationTime); + else if (workInProgressRootExitStatus === RootSuspendedWithDelay) + if (workInProgressRootHasPendingPing) + prepareFreshStack(root$jscomp$0, expirationTime); + else { + var lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + } if (null !== workInProgress) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + lastPendingTime = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; null === prevDispatcher && (prevDispatcher = ContextOnlyDispatcher); ReactCurrentDispatcher.current = ContextOnlyDispatcher; @@ -5196,8 +5592,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) return ( - (workPhase = prevWorkPhase), - resetContextDependences(), + (executionContext = lastPendingTime), + resetContextDependencies(), (ReactCurrentDispatcher.current = prevDispatcher), renderRoot.bind(null, root$jscomp$0, currentTime) ); @@ -5209,16 +5605,16 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); else - for (; null !== workInProgress && !shouldYield(); ) + for (; null !== workInProgress && !Scheduler_shouldYield(); ) workInProgress = performUnitOfWork(workInProgress); break; } catch (thrownValue) { - resetContextDependences(); + resetContextDependencies(); resetHooks(); currentTime = workInProgress; if (null === currentTime || null === currentTime.return) throw (prepareFreshStack(root$jscomp$0, expirationTime), - (workPhase = prevWorkPhase), + (executionContext = lastPendingTime), thrownValue); a: { var root = root$jscomp$0, @@ -5233,29 +5629,41 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; + var thenable = value, + hasInvisibleParentBoundary = + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext); value = returnFiber; do { - if ( - 13 === value.tag && - (void 0 === value.memoizedProps.fallback - ? 0 - : null === value.memoizedState) - ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === value.tag)) + null !== value.memoizedState + ? (JSCompiler_temp = !1) + : ((JSCompiler_temp = value.memoizedProps), + (JSCompiler_temp = + void 0 === JSCompiler_temp.fallback + ? !1 + : !0 !== JSCompiler_temp.unstable_avoidThisFallback + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0)); + if (JSCompiler_temp) { returnFiber = value.updateQueue; null === returnFiber ? ((returnFiber = new Set()), returnFiber.add(thenable), (value.updateQueue = returnFiber)) : returnFiber.add(thenable); - if (0 === (value.mode & 1)) { + if (0 === (value.mode & 2)) { value.effectTag |= 64; sourceFiber.effectTag &= -1957; 1 === sourceFiber.tag && (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((renderExpirationTime$jscomp$0 = createUpdate( - 1073741823 + 1073741823, + null )), (renderExpirationTime$jscomp$0.tag = 2), enqueueUpdate( @@ -5267,15 +5675,15 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { } sourceFiber = root; root = renderExpirationTime$jscomp$0; - var pingCache = sourceFiber.pingCache; - null === pingCache - ? ((pingCache = sourceFiber.pingCache = new PossiblyWeakMap()), + hasInvisibleParentBoundary = sourceFiber.pingCache; + null === hasInvisibleParentBoundary + ? ((hasInvisibleParentBoundary = sourceFiber.pingCache = new PossiblyWeakMap()), (returnFiber = new Set()), - pingCache.set(thenable, returnFiber)) - : ((returnFiber = pingCache.get(thenable)), + hasInvisibleParentBoundary.set(thenable, returnFiber)) + : ((returnFiber = hasInvisibleParentBoundary.get(thenable)), void 0 === returnFiber && ((returnFiber = new Set()), - pingCache.set(thenable, returnFiber))); + hasInvisibleParentBoundary.set(thenable, returnFiber))); returnFiber.has(root) || (returnFiber.add(root), (sourceFiber = pingSuspendedRoot.bind( @@ -5297,11 +5705,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { getStackByFiberInDevAndProd(sourceFiber) ); } - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootErrored; + workInProgressRootExitStatus !== RootCompleted && + (workInProgressRootExitStatus = RootErrored); value = createCapturedValue(value, sourceFiber); sourceFiber = returnFiber; do { @@ -5353,76 +5758,144 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = completeUnitOfWork(currentTime); } while (1); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = lastPendingTime; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (null !== workInProgress) return renderRoot.bind(null, root$jscomp$0, expirationTime); } + root$jscomp$0.finishedWork = root$jscomp$0.current.alternate; + root$jscomp$0.finishedExpirationTime = expirationTime; if (resolveLocksOnRoot(root$jscomp$0, expirationTime)) return null; workInProgressRoot = null; switch (workInProgressRootExitStatus) { case RootIncomplete: - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); case RootErrored: return ( - (prevWorkPhase = root$jscomp$0.lastPendingTime), - root$jscomp$0.lastPendingTime < expirationTime - ? renderRoot.bind(null, root$jscomp$0, prevWorkPhase) + (lastPendingTime = root$jscomp$0.lastPendingTime), + lastPendingTime < expirationTime + ? renderRoot.bind(null, root$jscomp$0, lastPendingTime) : isSync - ? commitRoot.bind(null, root$jscomp$0, expirationTime) + ? commitRoot.bind(null, root$jscomp$0) : (prepareFreshStack(root$jscomp$0, expirationTime), - scheduleCallback( - 99, + scheduleSyncCallback( renderRoot.bind(null, root$jscomp$0, expirationTime) ), null) ); case RootSuspended: + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + !isSync && + ((isSync = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < isSync) + ) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); + lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + isSync + ); + return null; + } + return commitRoot.bind(null, root$jscomp$0); + case RootSuspendedWithDelay: if (!isSync) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); isSync = root$jscomp$0.lastPendingTime; - if (root$jscomp$0.lastPendingTime < expirationTime) + if (isSync < expirationTime) return renderRoot.bind(null, root$jscomp$0, isSync); - if ( - 1073741823 !== workInProgressRootMostRecentEventTime && - ((prevWorkPhase = - 10 * (1073741822 - workInProgressRootMostRecentEventTime) - 5e3), - (isSync = now()), - (prevWorkPhase = isSync - prevWorkPhase), - (prevWorkPhase = - (120 > prevWorkPhase - ? 120 - : 480 > prevWorkPhase - ? 480 - : 1080 > prevWorkPhase - ? 1080 - : 1920 > prevWorkPhase - ? 1920 - : 3e3 > prevWorkPhase - ? 3e3 - : 4320 > prevWorkPhase - ? 4320 - : 1960 * ceil(prevWorkPhase / 1960)) - prevWorkPhase), - (isSync = 10 * (1073741822 - expirationTime) - isSync), - isSync < prevWorkPhase && (prevWorkPhase = isSync), - (isSync = prevWorkPhase), - 10 < isSync) - ) + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (isSync = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (isSync = 0) + : ((isSync = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (lastPendingTime = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - lastPendingTime), + (isSync = lastPendingTime - isSync), + 0 > isSync && (isSync = 0), + (isSync = + (120 > isSync + ? 120 + : 480 > isSync + ? 480 + : 1080 > isSync + ? 1080 + : 1920 > isSync + ? 1920 + : 3e3 > isSync + ? 3e3 + : 4320 > isSync + ? 4320 + : 1960 * ceil(isSync / 1960)) - isSync), + expirationTime < isSync && (isSync = expirationTime)); + if (10 < isSync) return ( (root$jscomp$0.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root$jscomp$0, expirationTime), + commitRoot.bind(null, root$jscomp$0), isSync )), null ); } - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return commitRoot.bind(null, root$jscomp$0); case RootCompleted: - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return !isSync && + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig && + ((lastPendingTime = workInProgressRootLatestProcessedExpirationTime), + (prevDispatcher = workInProgressRootCanSuspendUsingConfig), + (expirationTime = prevDispatcher.busyMinDurationMs | 0), + 0 >= expirationTime + ? (expirationTime = 0) + : ((isSync = prevDispatcher.busyDelayMs | 0), + (lastPendingTime = + now() - + (10 * (1073741821 - lastPendingTime) - + (prevDispatcher.timeoutMs | 0 || 5e3))), + (expirationTime = + lastPendingTime <= isSync + ? 0 + : isSync + expirationTime - lastPendingTime)), + 10 < expirationTime) + ? ((root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + expirationTime + )), + null) + : commitRoot.bind(null, root$jscomp$0); default: - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } } +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 1 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 1 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} function performUnitOfWork(unitOfWork) { var next = beginWork$$1( unitOfWork.alternate, @@ -5485,7 +5958,7 @@ function completeUnitOfWork(unitOfWork) { else if (newProps) { current = requiredContext(contextStackCursor$1.current); var type$jscomp$0 = type; - var instance = newProps; + var _instance5 = newProps; var rootContainerInstance = renderExpirationTime$jscomp$0, internalInstanceHandle = current$$1, tag = allocateTag(); @@ -5493,7 +5966,7 @@ function completeUnitOfWork(unitOfWork) { var updatePayload = diffProperties( null, emptyObject, - instance, + _instance5, type$jscomp$0.validAttributes ); ReactNativePrivateInterface.UIManager.createView( @@ -5506,22 +5979,24 @@ function completeUnitOfWork(unitOfWork) { tag, type$jscomp$0 ); - instanceCache[tag] = internalInstanceHandle; - instanceProps[tag] = instance; - instance = rootContainerInstance; - appendAllChildren(instance, current$$1, !1, !1); + instanceCache.set(tag, internalInstanceHandle); + instanceProps.set(tag, _instance5); + _instance5 = rootContainerInstance; + appendAllChildren(_instance5, current$$1, !1, !1); finalizeInitialChildren( - instance, + _instance5, type, newProps, renderExpirationTime$jscomp$0, current ) && (current$$1.effectTag |= 4); - current$$1.stateNode = instance; + current$$1.stateNode = _instance5; null !== current$$1.ref && (current$$1.effectTag |= 128); } else if (null === current$$1.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -5535,29 +6010,36 @@ function completeUnitOfWork(unitOfWork) { else { if ("string" !== typeof newProps && null === current$$1.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); - current = requiredContext(rootInstanceStackCursor.current); - type = requiredContext(contextStackCursor$1.current); - renderExpirationTime$jscomp$0 = current$$1; - if (!type.isInAParentText) + type = requiredContext(rootInstanceStackCursor.current); + renderExpirationTime$jscomp$0 = requiredContext( + contextStackCursor$1.current + ); + current = current$$1; + if (!renderExpirationTime$jscomp$0.isInAParentText) throw ReactError( - "Text strings must be rendered within a component." + Error( + "Text strings must be rendered within a component." + ) ); - type = allocateTag(); + renderExpirationTime$jscomp$0 = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - type, + renderExpirationTime$jscomp$0, "RCTRawText", - current, + type, { text: newProps } ); - instanceCache[type] = current$$1; - renderExpirationTime$jscomp$0.stateNode = type; + instanceCache.set(renderExpirationTime$jscomp$0, current$$1); + current.stateNode = renderExpirationTime$jscomp$0; } break; case 11: break; case 13: + pop(suspenseStackCursor, current$$1); newProps = current$$1.memoizedState; if (0 !== (current$$1.effectTag & 64)) { current$$1.expirationTime = renderExpirationTime$jscomp$0; @@ -5570,23 +6052,33 @@ function completeUnitOfWork(unitOfWork) { (renderExpirationTime$jscomp$0 = null !== type), newProps || null === type || - ((type = type.fallbackExpirationTime), - type < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = type), - (type = current.child.sibling), + ((type = current.child.sibling), null !== type && - ((current = current$$1.firstEffect), - null !== current + ((_instance5 = current$$1.firstEffect), + null !== _instance5 ? ((current$$1.firstEffect = type), - (type.nextEffect = current)) + (type.nextEffect = _instance5)) : ((current$$1.firstEffect = current$$1.lastEffect = type), (type.nextEffect = null)), (type.effectTag = 8)))); - newProps && + if ( + newProps && !renderExpirationTime$jscomp$0 && - 0 !== (current$$1.mode & 1) && - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); + 0 !== (current$$1.mode & 2) + ) + if ( + (null === current && + !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; if (newProps || renderExpirationTime$jscomp$0) current$$1.effectTag |= 4; break; @@ -5613,28 +6105,162 @@ function completeUnitOfWork(unitOfWork) { case 18: break; case 19: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (null === newProps) break; + type = 0 !== (current$$1.effectTag & 64); + _instance5 = newProps.rendering; + if (null === _instance5) + if (type) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = current$$1.child; null !== current; ) { + _instance5 = findFirstSuspended(current); + if (null !== _instance5) { + current$$1.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + newProps = _instance5.updateQueue; + null !== newProps && + ((current$$1.updateQueue = newProps), + (current$$1.effectTag |= 4)); + current$$1.firstEffect = current$$1.lastEffect = null; + newProps = renderExpirationTime$jscomp$0; + for (current = current$$1.child; null !== current; ) + (renderExpirationTime$jscomp$0 = current), + (type = newProps), + (renderExpirationTime$jscomp$0.effectTag &= 2), + (renderExpirationTime$jscomp$0.nextEffect = null), + (renderExpirationTime$jscomp$0.firstEffect = null), + (renderExpirationTime$jscomp$0.lastEffect = null), + (_instance5 = + renderExpirationTime$jscomp$0.alternate), + null === _instance5 + ? ((renderExpirationTime$jscomp$0.childExpirationTime = 0), + (renderExpirationTime$jscomp$0.expirationTime = type), + (renderExpirationTime$jscomp$0.child = null), + (renderExpirationTime$jscomp$0.memoizedProps = null), + (renderExpirationTime$jscomp$0.memoizedState = null), + (renderExpirationTime$jscomp$0.updateQueue = null), + (renderExpirationTime$jscomp$0.dependencies = null)) + : ((renderExpirationTime$jscomp$0.childExpirationTime = + _instance5.childExpirationTime), + (renderExpirationTime$jscomp$0.expirationTime = + _instance5.expirationTime), + (renderExpirationTime$jscomp$0.child = + _instance5.child), + (renderExpirationTime$jscomp$0.memoizedProps = + _instance5.memoizedProps), + (renderExpirationTime$jscomp$0.memoizedState = + _instance5.memoizedState), + (renderExpirationTime$jscomp$0.updateQueue = + _instance5.updateQueue), + (type = _instance5.dependencies), + (renderExpirationTime$jscomp$0.dependencies = + null === type + ? null + : { + expirationTime: type.expirationTime, + firstContext: type.firstContext, + listeners: type.listeners, + responders: type.responders + })), + (current = current.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & + SubtreeSuspenseContextMask) | + ForceSuspenseFallback, + current$$1 + ); + current$$1 = current$$1.child; + break a; + } + current = current.sibling; + } + } + else { + if (!type) + if ( + ((current = findFirstSuspended(_instance5)), null !== current) + ) { + if ( + ((current$$1.effectTag |= 64), + (type = !0), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && "hidden" === newProps.tailMode) + ) { + current = current.updateQueue; + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)); + current$$1 = current$$1.lastEffect = newProps.lastEffect; + null !== current$$1 && (current$$1.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((current$$1.effectTag |= 64), + (type = !0), + cutOffTailIfNeeded(newProps, !1), + (current$$1.expirationTime = current$$1.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((_instance5.sibling = current$$1.child), + (current$$1.child = _instance5)) + : ((current = newProps.last), + null !== current + ? (current.sibling = _instance5) + : (current$$1.child = _instance5), + (newProps.last = _instance5)); + } + if (null !== newProps.tail) { + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500); + current = newProps.tail; + newProps.rendering = current; + newProps.tail = current.sibling; + newProps.lastEffect = current$$1.lastEffect; + current.sibling = null; + newProps = suspenseStackCursor.current; + newProps = type + ? (newProps & SubtreeSuspenseContextMask) | + ForceSuspenseFallback + : newProps & SubtreeSuspenseContextMask; + push(suspenseStackCursor, newProps, current$$1); + current$$1 = current; + break a; + } break; case 20: break; default: throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } current$$1 = null; } newProps = workInProgress; if (1 === renderExpirationTime || 1 !== newProps.childExpirationTime) { - renderExpirationTime$jscomp$0 = 0; - for (type = newProps.child; null !== type; ) - (current = type.expirationTime), - (instance = type.childExpirationTime), - current > renderExpirationTime$jscomp$0 && - (renderExpirationTime$jscomp$0 = current), - instance > renderExpirationTime$jscomp$0 && - (renderExpirationTime$jscomp$0 = instance), - (type = type.sibling); - newProps.childExpirationTime = renderExpirationTime$jscomp$0; + current = 0; + for ( + renderExpirationTime$jscomp$0 = newProps.child; + null !== renderExpirationTime$jscomp$0; + + ) + (type = renderExpirationTime$jscomp$0.expirationTime), + (_instance5 = renderExpirationTime$jscomp$0.childExpirationTime), + type > current && (current = type), + _instance5 > current && (current = _instance5), + (renderExpirationTime$jscomp$0 = + renderExpirationTime$jscomp$0.sibling); + newProps.childExpirationTime = current; } if (null !== current$$1) return current$$1; null !== unitOfWork && @@ -5666,8 +6292,8 @@ function completeUnitOfWork(unitOfWork) { (workInProgressRootExitStatus = RootCompleted); return null; } -function commitRoot(root, expirationTime) { - runWithPriority(99, commitRootImpl.bind(null, root, expirationTime)); +function commitRoot(root) { + runWithPriority(99, commitRootImpl.bind(null, root)); null !== rootWithPendingPassiveEffects && ((root = getCurrentPriorityLevel()), scheduleCallback(root, function() { @@ -5676,13 +6302,21 @@ function commitRoot(root, expirationTime) { })); return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); - var finishedWork = root.current.alternate; - if (null === finishedWork) - throw ReactError("Should have a work-in-progress root."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); + var finishedWork = root.finishedWork, + expirationTime = root.finishedExpirationTime; + if (null === finishedWork) return null; + root.finishedWork = null; + root.finishedExpirationTime = 0; + if (finishedWork === root.current) + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); root.callbackNode = null; root.callbackExpirationTime = 0; var updateExpirationTimeBeforeCommit = finishedWork.expirationTime, @@ -5699,14 +6333,14 @@ function commitRootImpl(root, expirationTime) { 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (childExpirationTimeBeforeCommit = finishedWork.firstEffect)) - : (childExpirationTimeBeforeCommit = finishedWork) - : (childExpirationTimeBeforeCommit = finishedWork.firstEffect); - if (null !== childExpirationTimeBeforeCommit) { - updateExpirationTimeBeforeCommit = workPhase; - workPhase = CommitPhase; + (updateExpirationTimeBeforeCommit = finishedWork.firstEffect)) + : (updateExpirationTimeBeforeCommit = finishedWork) + : (updateExpirationTimeBeforeCommit = finishedWork.firstEffect); + if (null !== updateExpirationTimeBeforeCommit) { + childExpirationTimeBeforeCommit = executionContext; + executionContext |= CommitContext; ReactCurrentOwner$2.current = null; - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5749,11 +6383,12 @@ function commitRootImpl(root, expirationTime) { case 6: case 4: case 17: - case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5761,12 +6396,12 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5801,24 +6436,26 @@ function commitRootImpl(root, expirationTime) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; null !== alternate && ((alternate.return = null), (alternate.child = null), (alternate.memoizedState = null), - (alternate.updateQueue = null)); + (alternate.updateQueue = null), + (alternate.dependencies = null)); } nextEffect = nextEffect.nextEffect; } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); root.current = finishedWork; - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (effectTag = expirationTime; null !== nextEffect; ) { @@ -5895,15 +6532,15 @@ function commitRootImpl(root, expirationTime) { case 12: break; case 13: + case 19: case 17: - break; case 20: break; - case 19: - break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5928,28 +6565,34 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); nextEffect = null; - workPhase = updateExpirationTimeBeforeCommit; + requestPaint(); + executionContext = childExpirationTimeBeforeCommit; } else root.current = finishedWork; - rootDoesHavePassiveEffects && - ((rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root)); - expirationTime = root.firstPendingTime; - 0 !== expirationTime - ? ((effectTag$jscomp$0 = requestCurrentTime()), - (effectTag$jscomp$0 = inferPriorityFromExpirationTime( - effectTag$jscomp$0, - expirationTime + if (rootDoesHavePassiveEffects) + (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root); + else + for (nextEffect = updateExpirationTimeBeforeCommit; null !== nextEffect; ) + (effectTag$jscomp$0 = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + (nextEffect = effectTag$jscomp$0); + effectTag$jscomp$0 = root.firstPendingTime; + 0 !== effectTag$jscomp$0 + ? ((current$$1$jscomp$1 = requestCurrentTime()), + (current$$1$jscomp$1 = inferPriorityFromExpirationTime( + current$$1$jscomp$1, + effectTag$jscomp$0 )), - scheduleCallbackForRoot(root, effectTag$jscomp$0, expirationTime)) + scheduleCallbackForRoot(root, current$$1$jscomp$1, effectTag$jscomp$0)) : (legacyErrorBoundariesThatAlreadyFailed = null); "function" === typeof onCommitFiberRoot && - onCommitFiberRoot(finishedWork.stateNode); - 1073741823 === expirationTime + onCommitFiberRoot(finishedWork.stateNode, expirationTime); + 1073741823 === effectTag$jscomp$0 ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -5959,31 +6602,42 @@ function commitRootImpl(root, expirationTime) { (root = firstUncaughtError), (firstUncaughtError = null), root); - if (workPhase === LegacyUnbatchedPhase) return null; - flushImmediateQueue(); + if ((executionContext & LegacyUnbatchedContext) !== NoContext) return null; + flushSyncCallbackQueue(); return null; } function flushPassiveEffects() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Cannot flush passive effects while already rendering."); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; for (root = root.current.firstEffect; null !== root; ) { try { var finishedWork = root; - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if (0 !== (finishedWork.effectTag & 512)) + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork), + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + } } catch (error) { - if (null === root) throw ReactError("Should be working on an effect."); + if (null === root) + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(root, error); } - root = root.nextEffect; + finishedWork = root.nextEffect; + root.nextEffect = null; + root = finishedWork; } - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); return !0; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -6024,11 +6678,18 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); workInProgressRoot === root && renderExpirationTime === suspendedTime - ? prepareFreshStack(root, renderExpirationTime) + ? workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ? prepareFreshStack(root, renderExpirationTime) + : (workInProgressRootHasPendingPing = !0) : root.lastPendingTime < suspendedTime || ((thenable = root.pingTime), (0 !== thenable && thenable < suspendedTime) || ((root.pingTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), (thenable = requestCurrentTime()), (thenable = inferPriorityFromExpirationTime(thenable, suspendedTime)), scheduleCallbackForRoot(root, thenable, suspendedTime))); @@ -6037,7 +6698,7 @@ function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(thenable); retryCache = requestCurrentTime(); - thenable = computeExpirationForFiber(retryCache, boundaryFiber); + thenable = computeExpirationForFiber(retryCache, boundaryFiber, null); retryCache = inferPriorityFromExpirationTime(retryCache, thenable); boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && @@ -6087,6 +6748,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, renderExpirationTime ); + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( current$$1, workInProgress, @@ -6094,6 +6760,39 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); return null !== workInProgress ? workInProgress.sibling : null; } + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); + break; + case 19: + updateExpirationTime = 0 !== (current$$1.effectTag & 64); + if (workInProgress.childExpirationTime < renderExpirationTime) + return ( + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ), + updateExpirationTime && (workInProgress.effectTag |= 64), + null + ); + if (updateExpirationTime) + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + updateExpirationTime = workInProgress.memoizedState; + null !== updateExpirationTime && + ((updateExpirationTime.rendering = null), + (updateExpirationTime.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); } return bailoutOnAlreadyFinishedWork( current$$1, @@ -6229,9 +6928,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { break; default: throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." + Error( + "Element type is invalid. Received a promise that resolves to: " + + context + + ". Lazy element type must resolve to a class or function." + ) ); } return workInProgress; @@ -6272,7 +6973,9 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime = workInProgress.updateQueue; if (null === updateExpirationTime) throw ReactError( - "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." + 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." + ) ); context = workInProgress.memoizedState; context = null !== context ? context.element : null; @@ -6427,16 +7130,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== oldValue; ) { - var list = oldValue.contextDependencies; + var list = oldValue.dependencies; if (null !== list) { getDerivedStateFromProps = oldValue.child; - for (var dependency = list.first; null !== dependency; ) { + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { if ( dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { 1 === oldValue.tag && - ((dependency = createUpdate(renderExpirationTime)), + ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), enqueueUpdate(oldValue, dependency)); oldValue.expirationTime < renderExpirationTime && @@ -6445,22 +7152,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); - dependency = renderExpirationTime; - for (var node = oldValue.return; null !== node; ) { - var alternate = node.alternate; - if (node.childExpirationTime < dependency) - (node.childExpirationTime = dependency), - null !== alternate && - alternate.childExpirationTime < dependency && - (alternate.childExpirationTime = dependency); - else if ( - null !== alternate && - alternate.childExpirationTime < dependency - ) - alternate.childExpirationTime = dependency; - else break; - node = node.return; - } + scheduleWorkOnParentPath( + oldValue.return, + renderExpirationTime + ); list.expirationTime < renderExpirationTime && (list.expirationTime = renderExpirationTime); break; @@ -6587,11 +7282,45 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ) ); + case 19: + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); }; +var onCommitFiberRoot = null, + onCommitFiberUnmount = null; +function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled || !hook.supportsFiber) return !0; + try { + var rendererID = hook.inject(internals); + onCommitFiberRoot = function(root) { + try { + hook.onCommitFiberRoot( + rendererID, + root, + void 0, + 64 === (root.current.effectTag & 64) + ); + } catch (err) {} + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) {} + }; + } catch (err) {} + return !0; +} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -6599,7 +7328,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.index = 0; this.ref = null; this.pendingProps = pendingProps; - this.contextDependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; + this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; this.effectTag = 0; this.lastEffect = this.firstEffect = this.nextEffect = null; @@ -6648,7 +7377,16 @@ function createWorkInProgress(current, pendingProps) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + pendingProps = current.dependencies; + workInProgress.dependencies = + null === pendingProps + ? null + : { + expirationTime: pendingProps.expirationTime, + firstContext: pendingProps.firstContext, + listeners: pendingProps.listeners, + responders: pendingProps.responders + }; workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; @@ -6676,12 +7414,16 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 3, expirationTime, key); + fiberTag = 8; + mode |= 7; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 2, expirationTime, key); + fiberTag = 8; + mode |= 1; + break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -6690,8 +7432,15 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.elementType = REACT_SUSPENSE_TYPE), (type.type = REACT_SUSPENSE_TYPE), + (type.elementType = REACT_SUSPENSE_TYPE), + (type.expirationTime = expirationTime), + type + ); + case REACT_SUSPENSE_LIST_TYPE: + return ( + (type = createFiber(19, pendingProps, key, mode)), + (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type ); @@ -6716,9 +7465,11 @@ function createFiberFromTypeAndProps( break a; } throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (null == type ? type : typeof type) + - "." + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (null == type ? type : typeof type) + + "." + ) ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -6732,14 +7483,6 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { elements.expirationTime = expirationTime; return elements; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - pendingProps = createFiber(8, pendingProps, key, mode); - mode = 0 === (mode & 1) ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; - pendingProps.elementType = mode; - pendingProps.type = mode; - pendingProps.expirationTime = expirationTime; - return pendingProps; -} function createFiberFromText(content, mode, expirationTime) { content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; @@ -6760,11 +7503,12 @@ function createFiberFromPortal(portal, mode, expirationTime) { }; return mode; } -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pingCache = this.pendingChildren = null; - this.pendingCommitExpirationTime = 0; + this.finishedExpirationTime = 0; this.finishedWork = null; this.timeoutHandle = -1; this.pendingContext = this.context = null; @@ -6776,10 +7520,12 @@ function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { if ("function" === typeof component.render) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } component = findCurrentHostFiber(fiber); @@ -6787,8 +7533,13 @@ function findHostInstance(component) { } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current, - currentTime = requestCurrentTime(); - current$$1 = computeExpirationForFiber(currentTime, current$$1); + currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + current$$1 = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); currentTime = container.current; a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; @@ -6798,7 +7549,9 @@ function updateContainer(element, container, parentComponent, callback) { 1 !== parentComponent.tag ) throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + 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 parentContext = parentComponent; do { @@ -6817,7 +7570,9 @@ function updateContainer(element, container, parentComponent, callback) { parentContext = parentContext.return; } while (null !== parentContext); throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (1 === parentComponent.tag) { @@ -6837,12 +7592,11 @@ function updateContainer(element, container, parentComponent, callback) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(current$$1); - callback.payload = { element: element }; + suspenseConfig = createUpdate(current$$1, suspenseConfig); + suspenseConfig.payload = { element: element }; container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - flushPassiveEffects(); - enqueueUpdate(currentTime, callback); + null !== container && (suspenseConfig.callback = container); + enqueueUpdate(currentTime, suspenseConfig); scheduleUpdateOnFiber(currentTime, current$$1); return current$$1; } @@ -6879,7 +7633,7 @@ function _inherits(subClass, superClass) { var getInspectorDataForViewTag = void 0; getInspectorDataForViewTag = function() { throw ReactError( - "getInspectorDataForViewTag() is not available in production" + Error("getInspectorDataForViewTag() is not available in production") ); }; function findNodeHandle(componentOrHandle) { @@ -6895,19 +7649,19 @@ function findNodeHandle(componentOrHandle) { ? componentOrHandle.canonical._nativeTag : componentOrHandle._nativeTag; } -_batchedUpdatesImpl = function(fn, a) { - if (0 !== workPhase) return fn(a); - workPhase = 1; +batchedUpdatesImpl = function(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= 1; try { return fn(a); } finally { - (workPhase = 0), flushImmediateQueue(); + (executionContext = prevExecutionContext), + executionContext === NoContext && flushSyncCallbackQueue(); } }; -_flushInteractiveUpdatesImpl = function() { - workPhase !== RenderPhase && - workPhase !== CommitPhase && - flushPendingDiscreteUpdates(); +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); }; var roots = new Map(), ReactNativeRenderer = { @@ -7021,6 +7775,14 @@ var roots = new Map(), })(React.Component); })(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + }, setNativeProps: function(handle, nativeProps) { null != handle._nativeTag && ((nativeProps = diffProperties( @@ -7039,7 +7801,7 @@ var roots = new Map(), render: function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = new FiberRootNode(containerTag, !1); + root = new FiberRootNode(containerTag, 0, !1); var uninitializedFiber = createFiber(3, null, null, 0); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -7196,7 +7958,8 @@ var roots = new Map(), findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, - setRefreshHandler: null + setRefreshHandler: null, + getCurrentFiber: null }) ); })({ diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index ee6d7826c4788c..097f5c59a48e11 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -15,10 +15,9 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -function ReactError(message) { - message = Error(message); - message.name = "Invariant Violation"; - return message; +function ReactError(error) { + error.name = "Invariant Violation"; + return error; } var eventPluginOrder = null, namesToPlugins = {}; @@ -29,16 +28,20 @@ function recomputePluginOrdering() { pluginIndex = eventPluginOrder.indexOf(pluginName); if (!(-1 < pluginIndex)) throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); if (!plugins[pluginIndex]) { if (!pluginModule.extractEvents) throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); plugins[pluginIndex] = pluginModule; pluginIndex = pluginModule.eventTypes; @@ -49,9 +52,11 @@ function recomputePluginOrdering() { eventName$jscomp$0 = eventName; if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ) ); eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -77,11 +82,13 @@ function recomputePluginOrdering() { : (JSCompiler_inline_result = !1); if (!JSCompiler_inline_result) throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } } @@ -90,9 +97,11 @@ function recomputePluginOrdering() { function publishRegistrationName(registrationName, pluginModule) { if (registrationNameModules[registrationName]) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); registrationNameModules[registrationName] = pluginModule; } @@ -141,7 +150,9 @@ function invokeGuardedCallbackAndCatchFirstError( caughtError = null; } else throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } @@ -159,7 +170,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; if (Array.isArray(dispatchListener)) - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null; @@ -172,7 +183,9 @@ function executeDirectDispatch(event) { function accumulateInto(current, next) { if (null == next) throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); if (null == current) return next; if (Array.isArray(current)) { @@ -209,7 +222,9 @@ var injection = { injectEventPluginOrder: function(injectedEventPluginOrder) { if (eventPluginOrder) throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); @@ -226,9 +241,11 @@ var injection = { ) { if (namesToPlugins[pluginName]) throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); namesToPlugins[pluginName] = pluginModule; isOrderingDirty = !0; @@ -270,11 +287,13 @@ function getListener(inst, registrationName) { if (inst) return null; if (listener && "function" !== typeof listener) throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); return listener; } @@ -438,7 +457,9 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { if (!(event instanceof this)) throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); event.destructor(); 10 > this.eventPool.length && this.eventPool.push(event); @@ -474,7 +495,8 @@ function timestampForTouch(touch) { } function getTouchIdentifier(_ref) { _ref = _ref.identifier; - if (null == _ref) throw ReactError("Touch object is missing identifier."); + if (null == _ref) + throw ReactError(Error("Touch object is missing identifier.")); return _ref; } function recordTouchStart(touch) { @@ -517,7 +539,7 @@ function recordTouchMove(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch move without a touch start.\nTouch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -535,7 +557,7 @@ function recordTouchEnd(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch end without a touch start.\nTouch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -589,7 +611,7 @@ var ResponderTouchHistoryStore = { function accumulate(current, next) { if (null == next) throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error("accumulate(...): Accumulated items must not be null or undefined.") ); return null == current ? next @@ -967,7 +989,9 @@ injection.injectEventPluginsByName({ directDispatchConfig = customDirectEventTypes[topLevelType]; if (!bubbleDispatchConfig && !directDispatchConfig) throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); topLevelType = SyntheticEvent.getPooled( bubbleDispatchConfig || directDispatchConfig, @@ -984,33 +1008,38 @@ injection.injectEventPluginsByName({ } } }); -var instanceCache = {}, - instanceProps = {}; +var instanceCache = new Map(), + instanceProps = new Map(); function getInstanceFromTag(tag) { - return instanceCache[tag] || null; + return instanceCache.get(tag) || null; } var restoreTarget = null, restoreQueue = null; function restoreStateOfTarget(target) { if (getInstanceFromNode(target)) throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } -function _batchedUpdatesImpl(fn, bookkeeping) { +function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } -function _flushInteractiveUpdatesImpl() {} -var isBatching = !1; +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { - if (isBatching) return fn(bookkeeping); - isBatching = !0; + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - if (((isBatching = !1), null !== restoreTarget || null !== restoreQueue)) + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) if ( - (_flushInteractiveUpdatesImpl(), + (flushDiscreteUpdatesImpl(), restoreTarget && ((bookkeeping = restoreTarget), (fn = restoreQueue), @@ -1047,7 +1076,9 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); if (eventQueue) throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); if (hasRethrowError) throw ((events = rethrowError), @@ -1095,13 +1126,13 @@ ReactNativePrivateInterface.RCTEventEmitter.register({ } }); getFiberCurrentPropsFromNode = function(stateNode) { - return instanceProps[stateNode._nativeTag] || null; + return instanceProps.get(stateNode._nativeTag) || null; }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { var tag = inst.stateNode._nativeTag; void 0 === tag && (tag = inst.stateNode.canonical._nativeTag); - if (!tag) throw ReactError("All native instances should have a tag."); + if (!tag) throw ReactError(Error("All native instances should have a tag.")); return tag; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1118,6 +1149,8 @@ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher") || (ReactSharedInternals.ReactCurrentDispatcher = { current: null }); +ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig") || + (ReactSharedInternals.ReactCurrentBatchConfig = { suspense: null }); var hasSymbol = "function" === typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, @@ -1131,11 +1164,13 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, + REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; -hasSymbol && Symbol.for("react.event_component"); -hasSymbol && Symbol.for("react.event_target"); -hasSymbol && Symbol.for("react.event_target.touch_hit"); +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; @@ -1149,8 +1184,6 @@ function getComponentName(type) { if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -1161,6 +1194,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1195,14 +1230,14 @@ function isFiberMountedImpl(fiber) { } function assertIsMounted(fiber) { if (2 !== isFiberMountedImpl(fiber)) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; if (!alternate) { alternate = isFiberMountedImpl(fiber); if (3 === alternate) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return 1 === alternate ? null : fiber; } for (var a = fiber, b = alternate; ; ) { @@ -1223,7 +1258,7 @@ function findCurrentFiberUsingSlowPath(fiber) { if (parentB === b) return assertIsMounted(parentA), alternate; parentB = parentB.sibling; } - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } if (a.return !== b.return) (a = parentA), (b = parentB); else { @@ -1260,17 +1295,21 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (!didFindChild) throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } } if (a.alternate !== b) throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (3 !== a.tag) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return a.stateNode.current === a ? fiber : alternate; } function findCurrentHostFiber(parent) { @@ -1585,7 +1624,9 @@ var ReactNativeFiberHostComponent = (function() { })(); function shim$1() { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } var getViewConfigForType = @@ -1600,11 +1641,11 @@ function allocateTag() { } function recursivelyUncacheFiberNode(node) { if ("number" === typeof node) - delete instanceCache[node], delete instanceProps[node]; + instanceCache.delete(node), instanceProps.delete(node); else { var tag = node._nativeTag; - delete instanceCache[tag]; - delete instanceProps[tag]; + instanceCache.delete(tag); + instanceProps.delete(tag); node._children.forEach(recursivelyUncacheFiberNode); } } @@ -1620,8 +1661,22 @@ function finalizeInitialChildren(parentInstance) { return !1; } var scheduleTimeout = setTimeout, - cancelTimeout = clearTimeout, - BEFORE_SLASH_RE = /^(.*)[\\\/]/; + cancelTimeout = clearTimeout; +function removeChild(parentInstance, child) { + recursivelyUncacheFiberNode(child); + var children = parentInstance._children; + child = children.indexOf(child); + children.splice(child, 1); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, + [], + [], + [], + [], + [child] + ); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; function getStackByFiberInDevAndProd(workInProgress) { var info = ""; do { @@ -1707,7 +1762,9 @@ function popTopLevelContextObject(fiber) { function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); @@ -1720,10 +1777,12 @@ function processChildContext(fiber, type, parentContext) { for (var contextKey in instance) if (!(contextKey in fiber)) throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); return Object.assign({}, parentContext, instance); } @@ -1745,7 +1804,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { var instance = workInProgress.stateNode; if (!instance) throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); didChange ? ((type = processChildContext(workInProgress, type, previousContext)), @@ -1756,38 +1817,11 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -var onCommitFiberRoot = null, - onCommitFiberUnmount = null; -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) {} - }; -} -function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - var rendererID = hook.inject(internals); - onCommitFiberRoot = catchErrors(function(root) { - hook.onCommitFiberRoot( - rendererID, - root, - void 0, - 64 === (root.current.effectTag & 64) - ); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) {} - return !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 = Scheduler.unstable_now, Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel, @@ -1797,10 +1831,11 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_LowPriority = Scheduler.unstable_LowPriority, Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, fakeCallbackNode = {}, - shouldYield = Scheduler.unstable_shouldYield, - immediateQueue = null, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, immediateQueueCallbackNode = null, - isFlushingImmediate = !1, + isFlushingSyncQueue = !1, initialTimeMs = Scheduler_now(), now = 1e4 > initialTimeMs @@ -1821,7 +1856,7 @@ function getCurrentPriorityLevel() { case Scheduler_IdlePriority: return 95; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function reactPriorityToSchedulerPriority(reactPriorityLevel) { @@ -1837,7 +1872,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case 95: return Scheduler_IdlePriority; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function runWithPriority(reactPriorityLevel, fn) { @@ -1845,46 +1880,47 @@ function runWithPriority(reactPriorityLevel, fn) { return Scheduler_runWithPriority(reactPriorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (99 === reactPriorityLevel) - return ( - null === immediateQueue - ? ((immediateQueue = [callback]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ))) - : immediateQueue.push(callback), - fakeCallbackNode - ); reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function flushImmediateQueue() { +function scheduleSyncCallback(callback) { + null === syncQueue + ? ((syncQueue = [callback]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(callback); + return fakeCallbackNode; +} +function flushSyncCallbackQueue() { null !== immediateQueueCallbackNode && Scheduler_cancelCallback(immediateQueueCallbackNode); - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && null !== immediateQueue) { - isFlushingImmediate = !0; +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; var i = 0; try { - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do callback = callback(!0); - while (null !== callback); - } - immediateQueue = null; + 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 !== immediateQueue && - (immediateQueue = immediateQueue.slice(i + 1)), + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ), error); } finally { - isFlushingImmediate = !1; + isFlushingSyncQueue = !1; } } } @@ -1892,7 +1928,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (1073741823 === expirationTime) return 99; if (1 === expirationTime) return 95; currentTime = - 10 * (1073741822 - expirationTime) - 10 * (1073741822 - currentTime); + 10 * (1073741821 - expirationTime) - 10 * (1073741821 - currentTime); return 0 >= currentTime ? 99 : 250 >= currentTime @@ -1974,7 +2010,7 @@ var valueCursor = { current: null }, currentlyRenderingFiber = null, lastContextDependency = null, lastContextWithAllBitsObserved = null; -function resetContextDependences() { +function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } function pushProvider(providerFiber, nextValue) { @@ -1987,14 +2023,32 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); providerFiber.type._context._currentValue = currentValue; } +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + for (; null !== parent; ) { + var alternate = parent.alternate; + if (parent.childExpirationTime < renderExpirationTime) + (parent.childExpirationTime = renderExpirationTime), + null !== alternate && + alternate.childExpirationTime < renderExpirationTime && + (alternate.childExpirationTime = renderExpirationTime); + else if ( + null !== alternate && + alternate.childExpirationTime < renderExpirationTime + ) + alternate.childExpirationTime = renderExpirationTime; + else break; + parent = parent.return; + } +} function prepareToReadContext(workInProgress, renderExpirationTime) { currentlyRenderingFiber = workInProgress; lastContextWithAllBitsObserved = lastContextDependency = null; - var currentDependencies = workInProgress.contextDependencies; - null !== currentDependencies && - currentDependencies.expirationTime >= renderExpirationTime && - (didReceiveUpdate = !0); - workInProgress.contextDependencies = null; + workInProgress = workInProgress.dependencies; + null !== workInProgress && + null !== workInProgress.firstContext && + (workInProgress.expirationTime >= renderExpirationTime && + (didReceiveUpdate = !0), + (workInProgress.firstContext = null)); } function readContext(context, observedBits) { if ( @@ -2008,12 +2062,16 @@ function readContext(context, observedBits) { if (null === lastContextDependency) { if (null === currentlyRenderingFiber) throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); lastContextDependency = observedBits; - currentlyRenderingFiber.contextDependencies = { - first: observedBits, - expirationTime: 0 + currentlyRenderingFiber.dependencies = { + expirationTime: 0, + firstContext: observedBits, + listeners: null, + responders: null }; } else lastContextDependency = lastContextDependency.next = observedBits; } @@ -2046,9 +2104,10 @@ function cloneUpdateQueue(currentQueue) { lastCapturedEffect: null }; } -function createUpdate(expirationTime) { +function createUpdate(expirationTime, suspenseConfig) { return { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, @@ -2164,8 +2223,10 @@ function processUpdateQueue( ((newFirstUpdate = update), (newBaseState = resultState)), newExpirationTime < updateExpirationTime && (newExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), (resultState = getStateFromUpdate( workInProgress, queue, @@ -2241,15 +2302,18 @@ function commitUpdateEffects(effect, instance) { var context = instance; if ("function" !== typeof _callback3) throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - _callback3 + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + _callback3 + ) ); _callback3.call(context); } effect = effect.nextEffect; } } -var emptyRefsObject = new React.Component().refs; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + emptyRefsObject = new React.Component().refs; function applyDerivedStateFromProps( workInProgress, ctor, @@ -2276,36 +2340,42 @@ var classComponentUpdater = { }, enqueueSetState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 1; + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 2; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 2; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); } }; @@ -2434,15 +2504,19 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); inst = element.stateNode; } if (!inst) throw ReactError( - "Missing owner for string ref " + - returnFiber + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + returnFiber + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); var stringRef = "" + returnFiber; if ( @@ -2462,13 +2536,17 @@ function coerceRef(returnFiber, current$$1, element) { } if ("string" !== typeof returnFiber) throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); if (!element._owner) throw ReactError( - "Element ref was specified as a string (" + - returnFiber + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + returnFiber + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } return returnFiber; @@ -2476,11 +2554,13 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) throw ReactError( - "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === Object.prototype.toString.call(newChild) + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + ) ); } function ChildReconciler(shouldTrackSideEffects) { @@ -2883,11 +2963,13 @@ function ChildReconciler(shouldTrackSideEffects) { var iteratorFn = getIteratorFn(newChildrenIterable); if ("function" !== typeof iteratorFn) throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); newChildrenIterable = iteratorFn.call(newChildrenIterable); if (null == newChildrenIterable) - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); for ( var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, @@ -3122,8 +3204,10 @@ function ChildReconciler(shouldTrackSideEffects) { case 0: throw ((returnFiber = returnFiber.type), ReactError( - (returnFiber.displayName || returnFiber.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (returnFiber.displayName || returnFiber.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) )); } return deleteRemainingChildren(returnFiber, currentFirstChild); @@ -3138,7 +3222,9 @@ var reconcileChildFibers = ChildReconciler(!0), function requiredContext(c) { if (c === NO_CONTEXT) throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); return c; } @@ -3176,6 +3262,50 @@ function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } +var SubtreeSuspenseContextMask = 1, + InvisibleParentSuspenseContext = 1, + ForceSuspenseFallback = 2, + suspenseStackCursor = { current: 0 }; +function findFirstSuspended(row) { + for (var node = row; null !== node; ) { + if (13 === node.tag) { + if (null !== node.memoizedState) return node; + } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { + if (0 !== (node.effectTag & 64)) return node; + } else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; +} +var currentListenerHookIndex = 0; +function updateListenerHook(responder, props) { + var dependencies = null.dependencies; + null === dependencies && + (dependencies = null.dependencies = { + expirationTime: 0, + firstContext: null, + listeners: [], + responders: null + }); + var listeners = dependencies.listeners; + null === listeners && (dependencies.listeners = listeners = []); + listeners.length === currentListenerHookIndex + ? (listeners.push({ responder: responder, props: props }), + currentListenerHookIndex++) + : ((listeners = listeners[currentListenerHookIndex++]), + (listeners.responder = responder), + (listeners.props = props)); +} var NoEffect$1 = 0, UnmountSnapshot = 2, UnmountMutation = 4, @@ -3200,7 +3330,9 @@ var NoEffect$1 = 0, numberOfReRenders = 0; function throwInvalidHookError() { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } function areHookInputsEqual(nextDeps, prevDeps) { @@ -3250,7 +3382,9 @@ function renderWithHooks( sideEffectTag = 0; if (current) throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); return workInProgress; } @@ -3286,7 +3420,9 @@ function updateWorkInProgressHook() { (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) - throw ReactError("Rendered more hooks than during the previous render."); + throw ReactError( + Error("Rendered more hooks than during the previous render.") + ); currentHook = nextCurrentHook; var newHook = { memoizedState: currentHook.memoizedState, @@ -3311,7 +3447,9 @@ function updateReducer(reducer) { queue = hook.queue; if (null === queue) throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); queue.lastRenderedReducer = reducer; if (0 < numberOfReRenders) { @@ -3354,8 +3492,10 @@ function updateReducer(reducer) { (firstRenderPhaseUpdate = newState)), updateExpirationTime > remainingExpirationTime && (remainingExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ), (newState = _update.eagerReducer === reducer ? _update.eagerState @@ -3434,7 +3574,9 @@ function mountDebugValue() {} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); var alternate = fiber.alternate; if ( @@ -3445,6 +3587,7 @@ function dispatchAction(fiber, queue, action) { ((didScheduleRenderPhaseUpdate = !0), (fiber = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, @@ -3460,24 +3603,29 @@ function dispatchAction(fiber, queue, action) { queue.next = fiber; } else { - flushPassiveEffects(); - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, fiber); - var _update2 = { - expirationTime: currentTime, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }, - _last = queue.last; - if (null === _last) _update2.next = _update2; + var currentTime = requestCurrentTime(), + _suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); + _suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: _suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var _last = queue.last; + if (null === _last) _suspenseConfig.next = _suspenseConfig; else { var first = _last.next; - null !== first && (_update2.next = first); - _last.next = _update2; + null !== first && (_suspenseConfig.next = first); + _last.next = _suspenseConfig; } - queue.last = _update2; + queue.last = _suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3486,8 +3634,8 @@ function dispatchAction(fiber, queue, action) { try { var currentState = queue.lastRenderedState, _eagerState = alternate(currentState, action); - _update2.eagerReducer = alternate; - _update2.eagerState = _eagerState; + _suspenseConfig.eagerReducer = alternate; + _suspenseConfig.eagerState = _eagerState; if (is(_eagerState, currentState)) return; } catch (error) { } finally { @@ -3506,7 +3654,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3579,7 +3728,8 @@ var ContextOnlyDispatcher = { ); return [hook.memoizedState, initialState]; }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, HooksDispatcherOnUpdate = { readContext: readContext, @@ -3633,7 +3783,8 @@ var ContextOnlyDispatcher = { useState: function(initialState) { return updateReducer(basicStateReducer, initialState); }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, hydrationParentFiber = null, nextHydratableInstance = null, @@ -4174,6 +4325,7 @@ function pushHostRootContext(workInProgress) { pushTopLevelContextObject(workInProgress, root.context, !1); pushHostContainer(workInProgress, root.containerInfo); } +var SUSPENDED_MARKER = {}; function updateSuspenseComponent( current$$1, workInProgress, @@ -4181,100 +4333,271 @@ function updateSuspenseComponent( ) { var mode = workInProgress.mode, nextProps = workInProgress.pendingProps, - nextState = workInProgress.memoizedState; - if (0 === (workInProgress.effectTag & 64)) { - nextState = null; - var nextDidTimeout = !1; - } else - (nextState = { - fallbackExpirationTime: - null !== nextState ? nextState.fallbackExpirationTime : 0 - }), + suspenseContext = suspenseStackCursor.current, + nextState = null, + nextDidTimeout = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || + (JSCompiler_temp = + 0 !== (suspenseContext & ForceSuspenseFallback) && + (null === current$$1 || null !== current$$1.memoizedState)); + JSCompiler_temp + ? ((nextState = SUSPENDED_MARKER), (nextDidTimeout = !0), - (workInProgress.effectTag &= -65); + (workInProgress.effectTag &= -65)) + : (null !== current$$1 && null === current$$1.memoizedState) || + void 0 === nextProps.fallback || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= InvisibleParentSuspenseContext); + suspenseContext &= SubtreeSuspenseContextMask; + push(suspenseStackCursor, suspenseContext, workInProgress); if (null === current$$1) if (nextDidTimeout) { - var nextFallbackChildren = nextProps.fallback; + nextProps = nextProps.fallback; current$$1 = createFiberFromFragment(null, mode, 0, null); - 0 === (workInProgress.mode & 1) && - (current$$1.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child); - mode = createFiberFromFragment( - nextFallbackChildren, + current$$1.return = workInProgress; + if (0 === (workInProgress.mode & 2)) + for ( + nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + current$$1.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = current$$1), + (nextDidTimeout = nextDidTimeout.sibling); + renderExpirationTime = createFiberFromFragment( + nextProps, mode, renderExpirationTime, null ); - current$$1.sibling = mode; - renderExpirationTime = current$$1; - renderExpirationTime.return = mode.return = workInProgress; + renderExpirationTime.return = workInProgress; + current$$1.sibling = renderExpirationTime; + mode = current$$1; } else - renderExpirationTime = mode = mountChildFibers( + mode = renderExpirationTime = mountChildFibers( workInProgress, null, nextProps.children, renderExpirationTime ); - else - null !== current$$1.memoizedState - ? ((mode = current$$1.child), - (nextFallbackChildren = mode.sibling), - nextDidTimeout - ? ((renderExpirationTime = nextProps.fallback), - (nextProps = createWorkInProgress(mode, mode.pendingProps, 0)), - 0 === (workInProgress.mode & 1) && - ((nextDidTimeout = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child), - nextDidTimeout !== mode.child && - (nextProps.child = nextDidTimeout)), - (mode = nextProps.sibling = createWorkInProgress( - nextFallbackChildren, - renderExpirationTime, - nextFallbackChildren.expirationTime - )), - (renderExpirationTime = nextProps), - (nextProps.childExpirationTime = 0), - (renderExpirationTime.return = mode.return = workInProgress)) - : (renderExpirationTime = mode = reconcileChildFibers( - workInProgress, - mode.child, - nextProps.children, - renderExpirationTime - ))) - : ((nextFallbackChildren = current$$1.child), - nextDidTimeout - ? ((nextDidTimeout = nextProps.fallback), - (nextProps = createFiberFromFragment(null, mode, 0, null)), - (nextProps.child = nextFallbackChildren), - 0 === (workInProgress.mode & 1) && - (nextProps.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child), - (mode = nextProps.sibling = createFiberFromFragment( - nextDidTimeout, - mode, - renderExpirationTime, - null - )), - (mode.effectTag |= 2), - (renderExpirationTime = nextProps), - (nextProps.childExpirationTime = 0), - (renderExpirationTime.return = mode.return = workInProgress)) - : (mode = renderExpirationTime = reconcileChildFibers( - workInProgress, - nextFallbackChildren, - nextProps.children, - renderExpirationTime - ))), - (workInProgress.stateNode = current$$1.stateNode); + else { + if (null !== current$$1.memoizedState) + if ( + ((suspenseContext = current$$1.child), + (mode = suspenseContext.sibling), + nextDidTimeout) + ) { + nextProps = nextProps.fallback; + renderExpirationTime = createWorkInProgress( + suspenseContext, + suspenseContext.pendingProps, + 0 + ); + renderExpirationTime.return = workInProgress; + if ( + 0 === (workInProgress.mode & 2) && + ((nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child), + nextDidTimeout !== suspenseContext.child) + ) + for ( + renderExpirationTime.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = renderExpirationTime), + (nextDidTimeout = nextDidTimeout.sibling); + nextProps = createWorkInProgress(mode, nextProps, mode.expirationTime); + nextProps.return = workInProgress; + renderExpirationTime.sibling = nextProps; + mode = renderExpirationTime; + renderExpirationTime.childExpirationTime = 0; + renderExpirationTime = nextProps; + } else + mode = renderExpirationTime = reconcileChildFibers( + workInProgress, + suspenseContext.child, + nextProps.children, + renderExpirationTime + ); + else if (((suspenseContext = current$$1.child), nextDidTimeout)) { + nextDidTimeout = nextProps.fallback; + nextProps = createFiberFromFragment(null, mode, 0, null); + nextProps.return = workInProgress; + nextProps.child = suspenseContext; + null !== suspenseContext && (suspenseContext.return = nextProps); + if (0 === (workInProgress.mode & 2)) + for ( + suspenseContext = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + nextProps.child = suspenseContext; + null !== suspenseContext; + + ) + (suspenseContext.return = nextProps), + (suspenseContext = suspenseContext.sibling); + renderExpirationTime = createFiberFromFragment( + nextDidTimeout, + mode, + renderExpirationTime, + null + ); + renderExpirationTime.return = workInProgress; + nextProps.sibling = renderExpirationTime; + renderExpirationTime.effectTag |= 2; + mode = nextProps; + nextProps.childExpirationTime = 0; + } else + renderExpirationTime = mode = reconcileChildFibers( + workInProgress, + suspenseContext, + nextProps.children, + renderExpirationTime + ); + workInProgress.stateNode = current$$1.stateNode; + } workInProgress.memoizedState = nextState; - workInProgress.child = renderExpirationTime; - return mode; + workInProgress.child = mode; + return renderExpirationTime; +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailExpiration = 0), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren( + current$$1, + workInProgress, + nextProps.children, + renderExpirationTime + ); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & ForceSuspenseFallback)) + (nextProps = + (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), + (workInProgress.effectTag |= 64); + else { + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) { + if (null !== current$$1.memoizedState) { + current$$1.expirationTime < renderExpirationTime && + (current$$1.expirationTime = renderExpirationTime); + var alternate = current$$1.alternate; + null !== alternate && + alternate.expirationTime < renderExpirationTime && + (alternate.expirationTime = renderExpirationTime); + scheduleWorkOnParentPath(current$$1.return, renderExpirationTime); + } + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) + break a; + current$$1 = current$$1.return; + } + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + nextProps &= SubtreeSuspenseContextMask; + } + push(suspenseStackCursor, nextProps, workInProgress); + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderExpirationTime = workInProgress.child; + for (revealOrder = null; null !== renderExpirationTime; ) + (nextProps = renderExpirationTime.alternate), + null !== nextProps && + null === findFirstSuspended(nextProps) && + (revealOrder = renderExpirationTime), + (renderExpirationTime = renderExpirationTime.sibling); + renderExpirationTime = revealOrder; + null === renderExpirationTime + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderExpirationTime.sibling), + (renderExpirationTime.sibling = null)); + initSuspenseListRenderState( + workInProgress, + !1, + revealOrder, + renderExpirationTime, + tailMode + ); + break; + case "backwards": + renderExpirationTime = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + nextProps = revealOrder.alternate; + if (null !== nextProps && null === findFirstSuspended(nextProps)) { + workInProgress.child = revealOrder; + break; + } + nextProps = revealOrder.sibling; + revealOrder.sibling = renderExpirationTime; + renderExpirationTime = revealOrder; + revealOrder = nextProps; + } + initSuspenseListRenderState( + workInProgress, + !0, + renderExpirationTime, + null, + tailMode + ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; + } + return workInProgress.child; } function bailoutOnAlreadyFinishedWork( current$$1, @@ -4282,10 +4605,10 @@ function bailoutOnAlreadyFinishedWork( renderExpirationTime ) { null !== current$$1 && - (workInProgress.contextDependencies = current$$1.contextDependencies); + (workInProgress.dependencies = current$$1.dependencies); if (workInProgress.childExpirationTime < renderExpirationTime) return null; if (null !== current$$1 && workInProgress.child !== current$$1.child) - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); if (null !== workInProgress.child) { current$$1 = workInProgress.child; renderExpirationTime = createWorkInProgress( @@ -4317,6 +4640,7 @@ var appendAllChildren = void 0, appendAllChildren = function(parent, workInProgress) { for (var node = workInProgress.child; null !== node; ) { if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); + else if (20 === node.tag) parent._children.push(node.stateNode.instance); else if (4 !== node.tag && null !== node.child) { node.child.return = node; node = node.child; @@ -4341,6 +4665,74 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { updateHostText$1 = function(current, workInProgress, oldText, newText) { oldText !== newText && (workInProgress.effectTag |= 4); }; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var _lastTailNode = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === _lastTailNode + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (_lastTailNode.sibling = null); + } +} +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + workInProgress.effectTag = (effectTag & -2049) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null + ); + case 18: + return null; + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} function createCapturedValue(value, source) { return { value: value, @@ -4348,24 +4740,18 @@ function createCapturedValue(value, source) { stack: getStackByFiberInDevAndProd(source) }; } +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") + ); function logCapturedError(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - if (error instanceof Error) { - capturedError = error.message; - var name = error.name; - try { - error.message = - (capturedError ? name + ": " + capturedError : name) + - "\n\nThis error is located at:" + - componentStack; - } catch (e) {} - } else - error = - "string" === typeof error - ? Error(error + "\n\nThis error is located at:" + componentStack) - : Error("Unspecified error at:" + componentStack); - ReactNativePrivateInterface.ExceptionsManager.handleException(error, !1); + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ) && console.error(capturedError.error); } var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; function logError(boundary, errorInfo) { @@ -4425,64 +4811,6 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } -function hideOrUnhideAllChildren(finishedWork, isHidden) { - for (var node = finishedWork; ; ) { - if (5 === node.tag) { - var instance = node.stateNode; - if (isHidden) { - var viewConfig = instance.viewConfig; - var updatePayload = diffProperties( - null, - emptyObject, - { style: { display: "none" } }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } else { - instance = node.stateNode; - updatePayload = node.memoizedProps; - viewConfig = instance.viewConfig; - var prevProps = Object.assign({}, updatePayload, { - style: [updatePayload.style, { display: "none" }] - }); - updatePayload = diffProperties( - null, - prevProps, - updatePayload, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } - } else { - if (6 === node.tag) throw Error("Not yet implemented."); - if (13 === node.tag && null !== node.memoizedState) { - instance = node.child.sibling; - instance.return = node; - node = instance; - continue; - } else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - } - if (node === finishedWork) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === finishedWork) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -} function commitUnmount(current$$1$jscomp$0) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -4530,6 +4858,20 @@ function commitUnmount(current$$1$jscomp$0) { unmountHostComponents(current$$1$jscomp$0); } } +function commitNestedUnmounts(root) { + for (var node = root; ; ) + if ((commitUnmount(node), null !== node.child && 4 !== node.tag)) + (node.child.return = node), (node = node.child); + else { + if (node === root) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === root) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} function isHostParent(fiber) { return 5 === fiber.tag || 3 === fiber.tag || 4 === fiber.tag; } @@ -4543,25 +4885,29 @@ function commitPlacement(finishedWork) { parent = parent.return; } throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } + parent = parentFiber.stateNode; switch (parentFiber.tag) { case 5: - parent = parentFiber.stateNode; var isContainer = !1; break; case 3: - parent = parentFiber.stateNode.containerInfo; + parent = parent.containerInfo; isContainer = !0; break; case 4: - parent = parentFiber.stateNode.containerInfo; + parent = parent.containerInfo; isContainer = !0; break; default: throw ReactError( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ) ); } parentFiber.effectTag & 16 && (parentFiber.effectTag &= -17); @@ -4591,25 +4937,26 @@ function commitPlacement(finishedWork) { } } for (var node = finishedWork; ; ) { - if (5 === node.tag || 6 === node.tag) { - var stateNode = node.stateNode; + var isHost = 5 === node.tag || 6 === node.tag; + if (isHost || 20 === node.tag) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; if (parentFiber) if (isContainer) { if ("number" === typeof parent) throw ReactError( - "Container does not support insertBefore operation" + Error("Container does not support insertBefore operation") ); } else { - var parentInstance = parent, - beforeChild = parentFiber, - children = parentInstance._children, + isHost = parent; + var beforeChild = parentFiber, + children = isHost._children, index = children.indexOf(stateNode); 0 <= index ? (children.splice(index, 1), (beforeChild = children.indexOf(beforeChild)), children.splice(beforeChild, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [index], [beforeChild], [], @@ -4619,7 +4966,7 @@ function commitPlacement(finishedWork) { : ((index = children.indexOf(beforeChild)), children.splice(index, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [], [], [ @@ -4636,16 +4983,16 @@ function commitPlacement(finishedWork) { ? ReactNativePrivateInterface.UIManager.setChildren(parent, [ "number" === typeof stateNode ? stateNode : stateNode._nativeTag ]) - : ((parentInstance = parent), + : ((isHost = parent), (children = "number" === typeof stateNode ? stateNode : stateNode._nativeTag), - (index = parentInstance._children), + (index = isHost._children), (beforeChild = index.indexOf(stateNode)), 0 <= beforeChild ? (index.splice(beforeChild, 1), index.push(stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [beforeChild], [index.length - 1], [], @@ -4654,7 +5001,7 @@ function commitPlacement(finishedWork) { )) : (index.push(stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [], [], [children], @@ -4689,19 +5036,21 @@ function unmountHostComponents(current$$1) { a: for (;;) { if (null === currentParentIsValid) throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); + currentParent = currentParentIsValid.stateNode; switch (currentParentIsValid.tag) { case 5: - currentParent = currentParentIsValid.stateNode; currentParentIsContainer = !1; break a; case 3: - currentParent = currentParentIsValid.stateNode.containerInfo; + currentParent = currentParent.containerInfo; currentParentIsContainer = !0; break a; case 4: - currentParent = currentParentIsValid.stateNode.containerInfo; + currentParent = currentParent.containerInfo; currentParentIsContainer = !0; break a; } @@ -4709,52 +5058,37 @@ function unmountHostComponents(current$$1) { } currentParentIsValid = !0; } - if (5 === node.tag || 6 === node.tag) { - a: for (var root = node, node$jscomp$0 = root; ; ) - if ( - (commitUnmount(node$jscomp$0), - null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) - ) - (node$jscomp$0.child.return = node$jscomp$0), - (node$jscomp$0 = node$jscomp$0.child); - else { - if (node$jscomp$0 === root) break; - for (; null === node$jscomp$0.sibling; ) { - if (null === node$jscomp$0.return || node$jscomp$0.return === root) - break a; - node$jscomp$0 = node$jscomp$0.return; - } - node$jscomp$0.sibling.return = node$jscomp$0.return; - node$jscomp$0 = node$jscomp$0.sibling; - } - if (currentParentIsContainer) - (root = currentParent), - recursivelyUncacheFiberNode(node.stateNode), - ReactNativePrivateInterface.UIManager.manageChildren( - root, - [], - [], - [], - [], - [0] - ); - else { - root = currentParent; - var child = node.stateNode; - recursivelyUncacheFiberNode(child); - node$jscomp$0 = root._children; - child = node$jscomp$0.indexOf(child); - node$jscomp$0.splice(child, 1); + if (5 === node.tag || 6 === node.tag) + if ((commitNestedUnmounts(node), currentParentIsContainer)) { + var parentInstance = currentParent; + recursivelyUncacheFiberNode(node.stateNode); ReactNativePrivateInterface.UIManager.manageChildren( - root._nativeTag, + parentInstance, [], [], [], [], - [child] + [0] ); - } - } else if (4 === node.tag) { + } else removeChild(currentParent, node.stateNode); + else if (20 === node.tag) + if ( + ((parentInstance = node.stateNode.instance), + commitNestedUnmounts(node), + currentParentIsContainer) + ) { + var parentInstance$jscomp$0 = currentParent; + recursivelyUncacheFiberNode(parentInstance); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance$jscomp$0, + [], + [], + [], + [], + [0] + ); + } else removeChild(currentParent, parentInstance); + else if (4 === node.tag) { if (null !== node.child) { currentParent = node.stateNode.containerInfo; currentParentIsContainer = !0; @@ -4796,7 +5130,7 @@ function commitWork(current$$1, finishedWork) { finishedWork.updateQueue = null; null !== updatePayload && ((finishedWork = instance.viewConfig), - (instanceProps[instance._nativeTag] = newProps), + instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, current$$1, @@ -4814,7 +5148,9 @@ function commitWork(current$$1, finishedWork) { case 6: if (null === finishedWork.stateNode) throw ReactError( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ) ); ReactNativePrivateInterface.UIManager.updateView( finishedWork.stateNode, @@ -4822,44 +5158,99 @@ function commitWork(current$$1, finishedWork) { { text: finishedWork.memoizedProps } ); break; - case 20: - break; case 3: break; case 12: break; case 13: - commitSuspenseComponent(finishedWork); + instance = finishedWork; + null === finishedWork.memoizedState + ? (newProps = !1) + : ((newProps = !0), + (instance = finishedWork.child), + (globalMostRecentFallbackTime = now())); + if (null !== instance) + a: for (current$$1 = instance; ; ) { + if (5 === current$$1.tag) + if (((updatePayload = current$$1.stateNode), newProps)) { + var viewConfig = updatePayload.viewConfig; + var updatePayload$jscomp$0 = diffProperties( + null, + emptyObject, + { style: { display: "none" } }, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } else { + updatePayload = current$$1.stateNode; + updatePayload$jscomp$0 = current$$1.memoizedProps; + viewConfig = updatePayload.viewConfig; + var prevProps = Object.assign({}, updatePayload$jscomp$0, { + style: [updatePayload$jscomp$0.style, { display: "none" }] + }); + updatePayload$jscomp$0 = diffProperties( + null, + prevProps, + updatePayload$jscomp$0, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } + else { + if (6 === current$$1.tag) throw Error("Not yet implemented."); + if (13 === current$$1.tag && null !== current$$1.memoizedState) { + updatePayload = current$$1.child.sibling; + updatePayload.return = current$$1; + current$$1 = updatePayload; + continue; + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + } + if (current$$1 === instance) break a; + for (; null === current$$1.sibling; ) { + if (null === current$$1.return || current$$1.return === instance) + break a; + current$$1 = current$$1.return; + } + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + attachSuspenseRetryListeners(finishedWork); + break; + case 19: + attachSuspenseRetryListeners(finishedWork); break; case 17: break; - case 19: + case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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 commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState, - newDidTimeout = void 0, - primaryChildParent = finishedWork; - null === newState - ? (newDidTimeout = !1) - : ((newDidTimeout = !0), - (primaryChildParent = finishedWork.child), - 0 === newState.fallbackExpirationTime && - (newState.fallbackExpirationTime = requestCurrentTime() - 500)); - null !== primaryChildParent && - hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); - newState = finishedWork.updateQueue; - if (null !== newState) { +function attachSuspenseRetryListeners(finishedWork) { + var thenables = finishedWork.updateQueue; + if (null !== thenables) { finishedWork.updateQueue = null; var retryCache = finishedWork.stateNode; null === retryCache && (retryCache = finishedWork.stateNode = new PossiblyWeakSet$1()); - newState.forEach(function(thenable) { + thenables.forEach(function(thenable) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); retryCache.has(thenable) || (retryCache.add(thenable), thenable.then(retry, retry)); @@ -4868,7 +5259,7 @@ function commitSuspenseComponent(finishedWork) { } var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; expirationTime.payload = { element: null }; var error = errorInfo.value; @@ -4879,7 +5270,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { @@ -4905,64 +5296,29 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { }); return expirationTime; } -function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null; - case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -2049) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: - return ( - (effectTag = workInProgress.effectTag), - effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null - ); - case 18: - return null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 19: - case 20: - return null; - default: - return null; - } -} var ceil = Math.ceil, ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - LegacyUnbatchedPhase = 2, - RenderPhase = 4, - CommitPhase = 5, + NoContext = 0, + LegacyUnbatchedContext = 8, + RenderContext = 16, + CommitContext = 32, RootIncomplete = 0, RootErrored = 1, RootSuspended = 2, - RootCompleted = 3, - workPhase = 0, + RootSuspendedWithDelay = 3, + RootCompleted = 4, + executionContext = NoContext, workInProgressRoot = null, workInProgress = null, renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, - workInProgressRootMostRecentEventTime = 1073741823, + workInProgressRootLatestProcessedExpirationTime = 1073741823, + workInProgressRootLatestSuspenseTimeout = 1073741823, + workInProgressRootCanSuspendUsingConfig = null, + workInProgressRootHasPendingPing = !1, + globalMostRecentFallbackTime = 0, + FALLBACK_THROTTLE_MS = 500, nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, @@ -4974,34 +5330,49 @@ var ceil = Math.ceil, rootWithNestedUpdates = null, currentEventTime = 0; function requestCurrentTime() { - return workPhase === RenderPhase || workPhase === CommitPhase - ? 1073741822 - ((now() / 10) | 0) + return (executionContext & (RenderContext | CommitContext)) !== NoContext + ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime ? currentEventTime - : (currentEventTime = 1073741822 - ((now() / 10) | 0)); -} -function computeExpirationForFiber(currentTime, fiber) { - if (0 === (fiber.mode & 1)) return 1073741823; - if (workPhase === RenderPhase) return renderExpirationTime; - switch (getCurrentPriorityLevel()) { - case 99: - currentTime = 1073741823; - break; - case 98: - currentTime = - 1073741822 - 10 * ((((1073741822 - currentTime + 15) / 10) | 0) + 1); - break; - case 97: - case 96: - currentTime = - 1073741822 - 25 * ((((1073741822 - currentTime + 500) / 25) | 0) + 1); - break; - case 95: - currentTime = 1; - break; - default: - throw ReactError("Expected a valid priority level"); - } + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); +} +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + fiber = fiber.mode; + if (0 === (fiber & 2)) return 1073741823; + var priorityLevel = getCurrentPriorityLevel(); + if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; + if ((executionContext & RenderContext) !== NoContext) + return renderExpirationTime; + if (null !== suspenseConfig) + currentTime = + 1073741821 - + 25 * + ((((1073741821 - + currentTime + + (suspenseConfig.timeoutMs | 0 || 5e3) / 10) / + 25) | + 0) + + 1); + else + switch (priorityLevel) { + case 99: + currentTime = 1073741823; + break; + case 98: + currentTime = + 1073741821 - 10 * ((((1073741821 - currentTime + 15) / 10) | 0) + 1); + break; + case 97: + case 96: + currentTime = + 1073741821 - 25 * ((((1073741821 - currentTime + 500) / 25) | 0) + 1); + break; + case 95: + currentTime = 1; + break; + default: + throw ReactError(Error("Expected a valid priority level")); + } null !== workInProgressRoot && currentTime === renderExpirationTime && --currentTime; @@ -5012,33 +5383,37 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) )); fiber = markUpdateTimeFromFiberToRoot(fiber, expirationTime); - if (null !== fiber) - if (((fiber.pingTime = 0), 1073741823 === expirationTime)) - if (workPhase === LegacyUnbatchedPhase) + if (null !== fiber) { + fiber.pingTime = 0; + var priorityLevel = getCurrentPriorityLevel(); + if (1073741823 === expirationTime) + if ( + (executionContext & LegacyUnbatchedContext) !== NoContext && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) for ( - expirationTime = renderRoot(fiber, 1073741823, !0); - null !== expirationTime; + var callback = renderRoot(fiber, 1073741823, !0); + null !== callback; ) - expirationTime = expirationTime(!0); + callback = callback(!0); else scheduleCallbackForRoot(fiber, 99, 1073741823), - 0 === workPhase && flushImmediateQueue(); - else { - var priorityLevel = getCurrentPriorityLevel(); - if (98 === priorityLevel) - if (null === rootsWithPendingDiscreteUpdates) - rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]]); - else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(fiber); - (void 0 === lastDiscreteTime || lastDiscreteTime > expirationTime) && - rootsWithPendingDiscreteUpdates.set(fiber, expirationTime); - } - scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); - } + executionContext === NoContext && flushSyncCallbackQueue(); + else scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); + (executionContext & 4) === NoContext || + (98 !== priorityLevel && 99 !== priorityLevel) || + (null === rootsWithPendingDiscreteUpdates + ? (rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]])) + : ((priorityLevel = rootsWithPendingDiscreteUpdates.get(fiber)), + (void 0 === priorityLevel || priorityLevel > expirationTime) && + rootsWithPendingDiscreteUpdates.set(fiber, expirationTime))); + } } function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { fiber.expirationTime < expirationTime && @@ -5079,21 +5454,28 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode); root.callbackExpirationTime = expirationTime; - existingCallbackNode = null; - 1073741823 !== expirationTime && - 1 !== expirationTime && - ((existingCallbackNode = 10 * (1073741822 - expirationTime) - now()), - 5e3 < existingCallbackNode && (existingCallbackNode = 5e3), - (existingCallbackNode = { timeout: existingCallbackNode })); - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - existingCallbackNode - ); + 1073741823 === expirationTime + ? (root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + )) + : ((existingCallbackNode = null), + 1 !== expirationTime && + (existingCallbackNode = { + timeout: 10 * (1073741821 - expirationTime) - now() + }), + (root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + existingCallbackNode + ))); } } function runRootCallback(root, callback, isSync) { @@ -5117,9 +5499,7 @@ function resolveLocksOnRoot(root, expirationTime) { return null !== firstBatch && firstBatch._defer && firstBatch._expirationTime >= expirationTime - ? ((root.finishedWork = root.current.alternate), - (root.pendingCommitExpirationTime = expirationTime), - scheduleCallback(97, function() { + ? (scheduleCallback(97, function() { firstBatch._onComplete(); return null; }), @@ -5131,13 +5511,14 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback(99, renderRoot.bind(null, root, expirationTime)); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = 0; + root.finishedWork = null; + root.finishedExpirationTime = 0; var timeoutHandle = root.timeoutHandle; -1 !== timeoutHandle && ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); @@ -5161,6 +5542,12 @@ function prepareFreshStack(root, expirationTime) { case 4: popHostContainer(interruptedWork); break; + case 13: + pop(suspenseStackCursor, interruptedWork); + break; + case 19: + pop(suspenseStackCursor, interruptedWork); + break; case 10: popProvider(interruptedWork); } @@ -5170,24 +5557,33 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = 1073741823; + workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = !1; } function renderRoot(root$jscomp$0, expirationTime, isSync) { - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); if (root$jscomp$0.firstPendingTime < expirationTime) return null; - if (root$jscomp$0.pendingCommitExpirationTime === expirationTime) - return ( - (root$jscomp$0.pendingCommitExpirationTime = 0), - commitRoot.bind(null, root$jscomp$0, expirationTime) - ); + if (isSync && root$jscomp$0.finishedExpirationTime === expirationTime) + return commitRoot.bind(null, root$jscomp$0); flushPassiveEffects(); - (root$jscomp$0 === workInProgressRoot && - expirationTime === renderExpirationTime) || + if ( + root$jscomp$0 !== workInProgressRoot || + expirationTime !== renderExpirationTime + ) prepareFreshStack(root$jscomp$0, expirationTime); + else if (workInProgressRootExitStatus === RootSuspendedWithDelay) + if (workInProgressRootHasPendingPing) + prepareFreshStack(root$jscomp$0, expirationTime); + else { + var lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + } if (null !== workInProgress) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + lastPendingTime = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; null === prevDispatcher && (prevDispatcher = ContextOnlyDispatcher); ReactCurrentDispatcher.current = ContextOnlyDispatcher; @@ -5196,8 +5592,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) return ( - (workPhase = prevWorkPhase), - resetContextDependences(), + (executionContext = lastPendingTime), + resetContextDependencies(), (ReactCurrentDispatcher.current = prevDispatcher), renderRoot.bind(null, root$jscomp$0, currentTime) ); @@ -5209,16 +5605,16 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); else - for (; null !== workInProgress && !shouldYield(); ) + for (; null !== workInProgress && !Scheduler_shouldYield(); ) workInProgress = performUnitOfWork(workInProgress); break; } catch (thrownValue) { - resetContextDependences(); + resetContextDependencies(); resetHooks(); currentTime = workInProgress; if (null === currentTime || null === currentTime.return) throw (prepareFreshStack(root$jscomp$0, expirationTime), - (workPhase = prevWorkPhase), + (executionContext = lastPendingTime), thrownValue); a: { var root = root$jscomp$0, @@ -5233,29 +5629,41 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; + var thenable = value, + hasInvisibleParentBoundary = + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext); value = returnFiber; do { - if ( - 13 === value.tag && - (void 0 === value.memoizedProps.fallback - ? 0 - : null === value.memoizedState) - ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === value.tag)) + null !== value.memoizedState + ? (JSCompiler_temp = !1) + : ((JSCompiler_temp = value.memoizedProps), + (JSCompiler_temp = + void 0 === JSCompiler_temp.fallback + ? !1 + : !0 !== JSCompiler_temp.unstable_avoidThisFallback + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0)); + if (JSCompiler_temp) { returnFiber = value.updateQueue; null === returnFiber ? ((returnFiber = new Set()), returnFiber.add(thenable), (value.updateQueue = returnFiber)) : returnFiber.add(thenable); - if (0 === (value.mode & 1)) { + if (0 === (value.mode & 2)) { value.effectTag |= 64; sourceFiber.effectTag &= -1957; 1 === sourceFiber.tag && (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((renderExpirationTime$jscomp$0 = createUpdate( - 1073741823 + 1073741823, + null )), (renderExpirationTime$jscomp$0.tag = 2), enqueueUpdate( @@ -5267,15 +5675,15 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { } sourceFiber = root; root = renderExpirationTime$jscomp$0; - var pingCache = sourceFiber.pingCache; - null === pingCache - ? ((pingCache = sourceFiber.pingCache = new PossiblyWeakMap()), + hasInvisibleParentBoundary = sourceFiber.pingCache; + null === hasInvisibleParentBoundary + ? ((hasInvisibleParentBoundary = sourceFiber.pingCache = new PossiblyWeakMap()), (returnFiber = new Set()), - pingCache.set(thenable, returnFiber)) - : ((returnFiber = pingCache.get(thenable)), + hasInvisibleParentBoundary.set(thenable, returnFiber)) + : ((returnFiber = hasInvisibleParentBoundary.get(thenable)), void 0 === returnFiber && ((returnFiber = new Set()), - pingCache.set(thenable, returnFiber))); + hasInvisibleParentBoundary.set(thenable, returnFiber))); returnFiber.has(root) || (returnFiber.add(root), (sourceFiber = pingSuspendedRoot.bind( @@ -5297,11 +5705,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { getStackByFiberInDevAndProd(sourceFiber) ); } - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootErrored; + workInProgressRootExitStatus !== RootCompleted && + (workInProgressRootExitStatus = RootErrored); value = createCapturedValue(value, sourceFiber); sourceFiber = returnFiber; do { @@ -5353,76 +5758,144 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = completeUnitOfWork(currentTime); } while (1); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = lastPendingTime; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; if (null !== workInProgress) return renderRoot.bind(null, root$jscomp$0, expirationTime); } + root$jscomp$0.finishedWork = root$jscomp$0.current.alternate; + root$jscomp$0.finishedExpirationTime = expirationTime; if (resolveLocksOnRoot(root$jscomp$0, expirationTime)) return null; workInProgressRoot = null; switch (workInProgressRootExitStatus) { case RootIncomplete: - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); case RootErrored: return ( - (prevWorkPhase = root$jscomp$0.lastPendingTime), - root$jscomp$0.lastPendingTime < expirationTime - ? renderRoot.bind(null, root$jscomp$0, prevWorkPhase) + (lastPendingTime = root$jscomp$0.lastPendingTime), + lastPendingTime < expirationTime + ? renderRoot.bind(null, root$jscomp$0, lastPendingTime) : isSync - ? commitRoot.bind(null, root$jscomp$0, expirationTime) + ? commitRoot.bind(null, root$jscomp$0) : (prepareFreshStack(root$jscomp$0, expirationTime), - scheduleCallback( - 99, + scheduleSyncCallback( renderRoot.bind(null, root$jscomp$0, expirationTime) ), null) ); case RootSuspended: + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + !isSync && + ((isSync = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < isSync) + ) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); + lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + isSync + ); + return null; + } + return commitRoot.bind(null, root$jscomp$0); + case RootSuspendedWithDelay: if (!isSync) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); isSync = root$jscomp$0.lastPendingTime; - if (root$jscomp$0.lastPendingTime < expirationTime) + if (isSync < expirationTime) return renderRoot.bind(null, root$jscomp$0, isSync); - if ( - 1073741823 !== workInProgressRootMostRecentEventTime && - ((prevWorkPhase = - 10 * (1073741822 - workInProgressRootMostRecentEventTime) - 5e3), - (isSync = now()), - (prevWorkPhase = isSync - prevWorkPhase), - (prevWorkPhase = - (120 > prevWorkPhase - ? 120 - : 480 > prevWorkPhase - ? 480 - : 1080 > prevWorkPhase - ? 1080 - : 1920 > prevWorkPhase - ? 1920 - : 3e3 > prevWorkPhase - ? 3e3 - : 4320 > prevWorkPhase - ? 4320 - : 1960 * ceil(prevWorkPhase / 1960)) - prevWorkPhase), - (isSync = 10 * (1073741822 - expirationTime) - isSync), - isSync < prevWorkPhase && (prevWorkPhase = isSync), - (isSync = prevWorkPhase), - 10 < isSync) - ) + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (isSync = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (isSync = 0) + : ((isSync = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (lastPendingTime = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - lastPendingTime), + (isSync = lastPendingTime - isSync), + 0 > isSync && (isSync = 0), + (isSync = + (120 > isSync + ? 120 + : 480 > isSync + ? 480 + : 1080 > isSync + ? 1080 + : 1920 > isSync + ? 1920 + : 3e3 > isSync + ? 3e3 + : 4320 > isSync + ? 4320 + : 1960 * ceil(isSync / 1960)) - isSync), + expirationTime < isSync && (isSync = expirationTime)); + if (10 < isSync) return ( (root$jscomp$0.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root$jscomp$0, expirationTime), + commitRoot.bind(null, root$jscomp$0), isSync )), null ); } - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return commitRoot.bind(null, root$jscomp$0); case RootCompleted: - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return !isSync && + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig && + ((lastPendingTime = workInProgressRootLatestProcessedExpirationTime), + (prevDispatcher = workInProgressRootCanSuspendUsingConfig), + (expirationTime = prevDispatcher.busyMinDurationMs | 0), + 0 >= expirationTime + ? (expirationTime = 0) + : ((isSync = prevDispatcher.busyDelayMs | 0), + (lastPendingTime = + now() - + (10 * (1073741821 - lastPendingTime) - + (prevDispatcher.timeoutMs | 0 || 5e3))), + (expirationTime = + lastPendingTime <= isSync + ? 0 + : isSync + expirationTime - lastPendingTime)), + 10 < expirationTime) + ? ((root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + expirationTime + )), + null) + : commitRoot.bind(null, root$jscomp$0); default: - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } } +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 1 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 1 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} function performUnitOfWork(unitOfWork) { var next = beginWork$$1( unitOfWork.alternate, @@ -5485,7 +5958,7 @@ function completeUnitOfWork(unitOfWork) { else if (newProps) { current = requiredContext(contextStackCursor$1.current); var type$jscomp$0 = type; - var instance = newProps; + var _instance5 = newProps; var rootContainerInstance = renderExpirationTime$jscomp$0, internalInstanceHandle = current$$1, tag = allocateTag(); @@ -5493,7 +5966,7 @@ function completeUnitOfWork(unitOfWork) { var updatePayload = diffProperties( null, emptyObject, - instance, + _instance5, type$jscomp$0.validAttributes ); ReactNativePrivateInterface.UIManager.createView( @@ -5506,22 +5979,24 @@ function completeUnitOfWork(unitOfWork) { tag, type$jscomp$0 ); - instanceCache[tag] = internalInstanceHandle; - instanceProps[tag] = instance; - instance = rootContainerInstance; - appendAllChildren(instance, current$$1, !1, !1); + instanceCache.set(tag, internalInstanceHandle); + instanceProps.set(tag, _instance5); + _instance5 = rootContainerInstance; + appendAllChildren(_instance5, current$$1, !1, !1); finalizeInitialChildren( - instance, + _instance5, type, newProps, renderExpirationTime$jscomp$0, current ) && (current$$1.effectTag |= 4); - current$$1.stateNode = instance; + current$$1.stateNode = _instance5; null !== current$$1.ref && (current$$1.effectTag |= 128); } else if (null === current$$1.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -5535,29 +6010,36 @@ function completeUnitOfWork(unitOfWork) { else { if ("string" !== typeof newProps && null === current$$1.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); - current = requiredContext(rootInstanceStackCursor.current); - type = requiredContext(contextStackCursor$1.current); - renderExpirationTime$jscomp$0 = current$$1; - if (!type.isInAParentText) + type = requiredContext(rootInstanceStackCursor.current); + renderExpirationTime$jscomp$0 = requiredContext( + contextStackCursor$1.current + ); + current = current$$1; + if (!renderExpirationTime$jscomp$0.isInAParentText) throw ReactError( - "Text strings must be rendered within a component." + Error( + "Text strings must be rendered within a component." + ) ); - type = allocateTag(); + renderExpirationTime$jscomp$0 = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - type, + renderExpirationTime$jscomp$0, "RCTRawText", - current, + type, { text: newProps } ); - instanceCache[type] = current$$1; - renderExpirationTime$jscomp$0.stateNode = type; + instanceCache.set(renderExpirationTime$jscomp$0, current$$1); + current.stateNode = renderExpirationTime$jscomp$0; } break; case 11: break; case 13: + pop(suspenseStackCursor, current$$1); newProps = current$$1.memoizedState; if (0 !== (current$$1.effectTag & 64)) { current$$1.expirationTime = renderExpirationTime$jscomp$0; @@ -5570,23 +6052,33 @@ function completeUnitOfWork(unitOfWork) { (renderExpirationTime$jscomp$0 = null !== type), newProps || null === type || - ((type = type.fallbackExpirationTime), - type < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = type), - (type = current.child.sibling), + ((type = current.child.sibling), null !== type && - ((current = current$$1.firstEffect), - null !== current + ((_instance5 = current$$1.firstEffect), + null !== _instance5 ? ((current$$1.firstEffect = type), - (type.nextEffect = current)) + (type.nextEffect = _instance5)) : ((current$$1.firstEffect = current$$1.lastEffect = type), (type.nextEffect = null)), (type.effectTag = 8)))); - newProps && + if ( + newProps && !renderExpirationTime$jscomp$0 && - 0 !== (current$$1.mode & 1) && - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); + 0 !== (current$$1.mode & 2) + ) + if ( + (null === current && + !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; if (newProps || renderExpirationTime$jscomp$0) current$$1.effectTag |= 4; break; @@ -5613,28 +6105,162 @@ function completeUnitOfWork(unitOfWork) { case 18: break; case 19: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (null === newProps) break; + type = 0 !== (current$$1.effectTag & 64); + _instance5 = newProps.rendering; + if (null === _instance5) + if (type) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = current$$1.child; null !== current; ) { + _instance5 = findFirstSuspended(current); + if (null !== _instance5) { + current$$1.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + newProps = _instance5.updateQueue; + null !== newProps && + ((current$$1.updateQueue = newProps), + (current$$1.effectTag |= 4)); + current$$1.firstEffect = current$$1.lastEffect = null; + newProps = renderExpirationTime$jscomp$0; + for (current = current$$1.child; null !== current; ) + (renderExpirationTime$jscomp$0 = current), + (type = newProps), + (renderExpirationTime$jscomp$0.effectTag &= 2), + (renderExpirationTime$jscomp$0.nextEffect = null), + (renderExpirationTime$jscomp$0.firstEffect = null), + (renderExpirationTime$jscomp$0.lastEffect = null), + (_instance5 = + renderExpirationTime$jscomp$0.alternate), + null === _instance5 + ? ((renderExpirationTime$jscomp$0.childExpirationTime = 0), + (renderExpirationTime$jscomp$0.expirationTime = type), + (renderExpirationTime$jscomp$0.child = null), + (renderExpirationTime$jscomp$0.memoizedProps = null), + (renderExpirationTime$jscomp$0.memoizedState = null), + (renderExpirationTime$jscomp$0.updateQueue = null), + (renderExpirationTime$jscomp$0.dependencies = null)) + : ((renderExpirationTime$jscomp$0.childExpirationTime = + _instance5.childExpirationTime), + (renderExpirationTime$jscomp$0.expirationTime = + _instance5.expirationTime), + (renderExpirationTime$jscomp$0.child = + _instance5.child), + (renderExpirationTime$jscomp$0.memoizedProps = + _instance5.memoizedProps), + (renderExpirationTime$jscomp$0.memoizedState = + _instance5.memoizedState), + (renderExpirationTime$jscomp$0.updateQueue = + _instance5.updateQueue), + (type = _instance5.dependencies), + (renderExpirationTime$jscomp$0.dependencies = + null === type + ? null + : { + expirationTime: type.expirationTime, + firstContext: type.firstContext, + listeners: type.listeners, + responders: type.responders + })), + (current = current.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & + SubtreeSuspenseContextMask) | + ForceSuspenseFallback, + current$$1 + ); + current$$1 = current$$1.child; + break a; + } + current = current.sibling; + } + } + else { + if (!type) + if ( + ((current = findFirstSuspended(_instance5)), null !== current) + ) { + if ( + ((current$$1.effectTag |= 64), + (type = !0), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && "hidden" === newProps.tailMode) + ) { + current = current.updateQueue; + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)); + current$$1 = current$$1.lastEffect = newProps.lastEffect; + null !== current$$1 && (current$$1.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((current$$1.effectTag |= 64), + (type = !0), + cutOffTailIfNeeded(newProps, !1), + (current$$1.expirationTime = current$$1.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((_instance5.sibling = current$$1.child), + (current$$1.child = _instance5)) + : ((current = newProps.last), + null !== current + ? (current.sibling = _instance5) + : (current$$1.child = _instance5), + (newProps.last = _instance5)); + } + if (null !== newProps.tail) { + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500); + current = newProps.tail; + newProps.rendering = current; + newProps.tail = current.sibling; + newProps.lastEffect = current$$1.lastEffect; + current.sibling = null; + newProps = suspenseStackCursor.current; + newProps = type + ? (newProps & SubtreeSuspenseContextMask) | + ForceSuspenseFallback + : newProps & SubtreeSuspenseContextMask; + push(suspenseStackCursor, newProps, current$$1); + current$$1 = current; + break a; + } break; case 20: break; default: throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } current$$1 = null; } newProps = workInProgress; if (1 === renderExpirationTime || 1 !== newProps.childExpirationTime) { - renderExpirationTime$jscomp$0 = 0; - for (type = newProps.child; null !== type; ) - (current = type.expirationTime), - (instance = type.childExpirationTime), - current > renderExpirationTime$jscomp$0 && - (renderExpirationTime$jscomp$0 = current), - instance > renderExpirationTime$jscomp$0 && - (renderExpirationTime$jscomp$0 = instance), - (type = type.sibling); - newProps.childExpirationTime = renderExpirationTime$jscomp$0; + current = 0; + for ( + renderExpirationTime$jscomp$0 = newProps.child; + null !== renderExpirationTime$jscomp$0; + + ) + (type = renderExpirationTime$jscomp$0.expirationTime), + (_instance5 = renderExpirationTime$jscomp$0.childExpirationTime), + type > current && (current = type), + _instance5 > current && (current = _instance5), + (renderExpirationTime$jscomp$0 = + renderExpirationTime$jscomp$0.sibling); + newProps.childExpirationTime = current; } if (null !== current$$1) return current$$1; null !== unitOfWork && @@ -5666,8 +6292,8 @@ function completeUnitOfWork(unitOfWork) { (workInProgressRootExitStatus = RootCompleted); return null; } -function commitRoot(root, expirationTime) { - runWithPriority(99, commitRootImpl.bind(null, root, expirationTime)); +function commitRoot(root) { + runWithPriority(99, commitRootImpl.bind(null, root)); null !== rootWithPendingPassiveEffects && ((root = getCurrentPriorityLevel()), scheduleCallback(root, function() { @@ -5676,13 +6302,21 @@ function commitRoot(root, expirationTime) { })); return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); - var finishedWork = root.current.alternate; - if (null === finishedWork) - throw ReactError("Should have a work-in-progress root."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); + var finishedWork = root.finishedWork, + expirationTime = root.finishedExpirationTime; + if (null === finishedWork) return null; + root.finishedWork = null; + root.finishedExpirationTime = 0; + if (finishedWork === root.current) + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); root.callbackNode = null; root.callbackExpirationTime = 0; var updateExpirationTimeBeforeCommit = finishedWork.expirationTime, @@ -5699,14 +6333,14 @@ function commitRootImpl(root, expirationTime) { 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (childExpirationTimeBeforeCommit = finishedWork.firstEffect)) - : (childExpirationTimeBeforeCommit = finishedWork) - : (childExpirationTimeBeforeCommit = finishedWork.firstEffect); - if (null !== childExpirationTimeBeforeCommit) { - updateExpirationTimeBeforeCommit = workPhase; - workPhase = CommitPhase; + (updateExpirationTimeBeforeCommit = finishedWork.firstEffect)) + : (updateExpirationTimeBeforeCommit = finishedWork) + : (updateExpirationTimeBeforeCommit = finishedWork.firstEffect); + if (null !== updateExpirationTimeBeforeCommit) { + childExpirationTimeBeforeCommit = executionContext; + executionContext |= CommitContext; ReactCurrentOwner$2.current = null; - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5749,11 +6383,12 @@ function commitRootImpl(root, expirationTime) { case 6: case 4: case 17: - case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5761,12 +6396,12 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5801,24 +6436,26 @@ function commitRootImpl(root, expirationTime) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; null !== alternate && ((alternate.return = null), (alternate.child = null), (alternate.memoizedState = null), - (alternate.updateQueue = null)); + (alternate.updateQueue = null), + (alternate.dependencies = null)); } nextEffect = nextEffect.nextEffect; } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); root.current = finishedWork; - nextEffect = childExpirationTimeBeforeCommit; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (effectTag = expirationTime; null !== nextEffect; ) { @@ -5895,15 +6532,15 @@ function commitRootImpl(root, expirationTime) { case 12: break; case 13: + case 19: case 17: - break; case 20: break; - case 19: - break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5928,28 +6565,34 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); nextEffect = null; - workPhase = updateExpirationTimeBeforeCommit; + requestPaint(); + executionContext = childExpirationTimeBeforeCommit; } else root.current = finishedWork; - rootDoesHavePassiveEffects && - ((rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root)); - expirationTime = root.firstPendingTime; - 0 !== expirationTime - ? ((effectTag$jscomp$0 = requestCurrentTime()), - (effectTag$jscomp$0 = inferPriorityFromExpirationTime( - effectTag$jscomp$0, - expirationTime + if (rootDoesHavePassiveEffects) + (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root); + else + for (nextEffect = updateExpirationTimeBeforeCommit; null !== nextEffect; ) + (effectTag$jscomp$0 = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + (nextEffect = effectTag$jscomp$0); + effectTag$jscomp$0 = root.firstPendingTime; + 0 !== effectTag$jscomp$0 + ? ((current$$1$jscomp$1 = requestCurrentTime()), + (current$$1$jscomp$1 = inferPriorityFromExpirationTime( + current$$1$jscomp$1, + effectTag$jscomp$0 )), - scheduleCallbackForRoot(root, effectTag$jscomp$0, expirationTime)) + scheduleCallbackForRoot(root, current$$1$jscomp$1, effectTag$jscomp$0)) : (legacyErrorBoundariesThatAlreadyFailed = null); "function" === typeof onCommitFiberRoot && - onCommitFiberRoot(finishedWork.stateNode); - 1073741823 === expirationTime + onCommitFiberRoot(finishedWork.stateNode, expirationTime); + 1073741823 === effectTag$jscomp$0 ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -5959,31 +6602,42 @@ function commitRootImpl(root, expirationTime) { (root = firstUncaughtError), (firstUncaughtError = null), root); - if (workPhase === LegacyUnbatchedPhase) return null; - flushImmediateQueue(); + if ((executionContext & LegacyUnbatchedContext) !== NoContext) return null; + flushSyncCallbackQueue(); return null; } function flushPassiveEffects() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Cannot flush passive effects while already rendering."); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; for (root = root.current.firstEffect; null !== root; ) { try { var finishedWork = root; - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if (0 !== (finishedWork.effectTag & 512)) + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork), + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + } } catch (error) { - if (null === root) throw ReactError("Should be working on an effect."); + if (null === root) + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(root, error); } - root = root.nextEffect; + finishedWork = root.nextEffect; + root.nextEffect = null; + root = finishedWork; } - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); return !0; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -6024,11 +6678,18 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); workInProgressRoot === root && renderExpirationTime === suspendedTime - ? prepareFreshStack(root, renderExpirationTime) + ? workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ? prepareFreshStack(root, renderExpirationTime) + : (workInProgressRootHasPendingPing = !0) : root.lastPendingTime < suspendedTime || ((thenable = root.pingTime), (0 !== thenable && thenable < suspendedTime) || ((root.pingTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), (thenable = requestCurrentTime()), (thenable = inferPriorityFromExpirationTime(thenable, suspendedTime)), scheduleCallbackForRoot(root, thenable, suspendedTime))); @@ -6037,7 +6698,7 @@ function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(thenable); retryCache = requestCurrentTime(); - thenable = computeExpirationForFiber(retryCache, boundaryFiber); + thenable = computeExpirationForFiber(retryCache, boundaryFiber, null); retryCache = inferPriorityFromExpirationTime(retryCache, thenable); boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && @@ -6087,6 +6748,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, renderExpirationTime ); + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( current$$1, workInProgress, @@ -6094,6 +6760,39 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); return null !== workInProgress ? workInProgress.sibling : null; } + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); + break; + case 19: + updateExpirationTime = 0 !== (current$$1.effectTag & 64); + if (workInProgress.childExpirationTime < renderExpirationTime) + return ( + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ), + updateExpirationTime && (workInProgress.effectTag |= 64), + null + ); + if (updateExpirationTime) + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + updateExpirationTime = workInProgress.memoizedState; + null !== updateExpirationTime && + ((updateExpirationTime.rendering = null), + (updateExpirationTime.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); } return bailoutOnAlreadyFinishedWork( current$$1, @@ -6229,9 +6928,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { break; default: throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." + Error( + "Element type is invalid. Received a promise that resolves to: " + + context + + ". Lazy element type must resolve to a class or function." + ) ); } return workInProgress; @@ -6272,7 +6973,9 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime = workInProgress.updateQueue; if (null === updateExpirationTime) throw ReactError( - "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." + 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." + ) ); context = workInProgress.memoizedState; context = null !== context ? context.element : null; @@ -6427,16 +7130,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== oldValue; ) { - var list = oldValue.contextDependencies; + var list = oldValue.dependencies; if (null !== list) { getDerivedStateFromProps = oldValue.child; - for (var dependency = list.first; null !== dependency; ) { + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { if ( dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { 1 === oldValue.tag && - ((dependency = createUpdate(renderExpirationTime)), + ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), enqueueUpdate(oldValue, dependency)); oldValue.expirationTime < renderExpirationTime && @@ -6445,22 +7152,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); - dependency = renderExpirationTime; - for (var node = oldValue.return; null !== node; ) { - var alternate = node.alternate; - if (node.childExpirationTime < dependency) - (node.childExpirationTime = dependency), - null !== alternate && - alternate.childExpirationTime < dependency && - (alternate.childExpirationTime = dependency); - else if ( - null !== alternate && - alternate.childExpirationTime < dependency - ) - alternate.childExpirationTime = dependency; - else break; - node = node.return; - } + scheduleWorkOnParentPath( + oldValue.return, + renderExpirationTime + ); list.expirationTime < renderExpirationTime && (list.expirationTime = renderExpirationTime); break; @@ -6587,11 +7282,45 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ) ); + case 19: + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); }; +var onCommitFiberRoot = null, + onCommitFiberUnmount = null; +function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled || !hook.supportsFiber) return !0; + try { + var rendererID = hook.inject(internals); + onCommitFiberRoot = function(root) { + try { + hook.onCommitFiberRoot( + rendererID, + root, + void 0, + 64 === (root.current.effectTag & 64) + ); + } catch (err) {} + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) {} + }; + } catch (err) {} + return !0; +} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -6599,7 +7328,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.index = 0; this.ref = null; this.pendingProps = pendingProps; - this.contextDependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; + this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; this.effectTag = 0; this.lastEffect = this.firstEffect = this.nextEffect = null; @@ -6648,7 +7377,16 @@ function createWorkInProgress(current, pendingProps) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + pendingProps = current.dependencies; + workInProgress.dependencies = + null === pendingProps + ? null + : { + expirationTime: pendingProps.expirationTime, + firstContext: pendingProps.firstContext, + listeners: pendingProps.listeners, + responders: pendingProps.responders + }; workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; @@ -6676,12 +7414,16 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 3, expirationTime, key); + fiberTag = 8; + mode |= 7; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 2, expirationTime, key); + fiberTag = 8; + mode |= 1; + break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -6690,8 +7432,15 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.elementType = REACT_SUSPENSE_TYPE), (type.type = REACT_SUSPENSE_TYPE), + (type.elementType = REACT_SUSPENSE_TYPE), + (type.expirationTime = expirationTime), + type + ); + case REACT_SUSPENSE_LIST_TYPE: + return ( + (type = createFiber(19, pendingProps, key, mode)), + (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type ); @@ -6716,9 +7465,11 @@ function createFiberFromTypeAndProps( break a; } throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (null == type ? type : typeof type) + - "." + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (null == type ? type : typeof type) + + "." + ) ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -6732,14 +7483,6 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { elements.expirationTime = expirationTime; return elements; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - pendingProps = createFiber(8, pendingProps, key, mode); - mode = 0 === (mode & 1) ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; - pendingProps.elementType = mode; - pendingProps.type = mode; - pendingProps.expirationTime = expirationTime; - return pendingProps; -} function createFiberFromText(content, mode, expirationTime) { content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; @@ -6760,11 +7503,12 @@ function createFiberFromPortal(portal, mode, expirationTime) { }; return mode; } -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pingCache = this.pendingChildren = null; - this.pendingCommitExpirationTime = 0; + this.finishedExpirationTime = 0; this.finishedWork = null; this.timeoutHandle = -1; this.pendingContext = this.context = null; @@ -6776,10 +7520,12 @@ function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { if ("function" === typeof component.render) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } component = findCurrentHostFiber(fiber); @@ -6787,8 +7533,13 @@ function findHostInstance(component) { } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current, - currentTime = requestCurrentTime(); - current$$1 = computeExpirationForFiber(currentTime, current$$1); + currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + current$$1 = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); currentTime = container.current; a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; @@ -6798,7 +7549,9 @@ function updateContainer(element, container, parentComponent, callback) { 1 !== parentComponent.tag ) throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + 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 parentContext = parentComponent; do { @@ -6817,7 +7570,9 @@ function updateContainer(element, container, parentComponent, callback) { parentContext = parentContext.return; } while (null !== parentContext); throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (1 === parentComponent.tag) { @@ -6837,12 +7592,11 @@ function updateContainer(element, container, parentComponent, callback) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(current$$1); - callback.payload = { element: element }; + suspenseConfig = createUpdate(current$$1, suspenseConfig); + suspenseConfig.payload = { element: element }; container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - flushPassiveEffects(); - enqueueUpdate(currentTime, callback); + null !== container && (suspenseConfig.callback = container); + enqueueUpdate(currentTime, suspenseConfig); scheduleUpdateOnFiber(currentTime, current$$1); return current$$1; } @@ -6879,7 +7633,7 @@ function _inherits(subClass, superClass) { var getInspectorDataForViewTag = void 0; getInspectorDataForViewTag = function() { throw ReactError( - "getInspectorDataForViewTag() is not available in production" + Error("getInspectorDataForViewTag() is not available in production") ); }; function findNodeHandle(componentOrHandle) { @@ -6895,19 +7649,19 @@ function findNodeHandle(componentOrHandle) { ? componentOrHandle.canonical._nativeTag : componentOrHandle._nativeTag; } -_batchedUpdatesImpl = function(fn, a) { - if (0 !== workPhase) return fn(a); - workPhase = 1; +batchedUpdatesImpl = function(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= 1; try { return fn(a); } finally { - (workPhase = 0), flushImmediateQueue(); + (executionContext = prevExecutionContext), + executionContext === NoContext && flushSyncCallbackQueue(); } }; -_flushInteractiveUpdatesImpl = function() { - workPhase !== RenderPhase && - workPhase !== CommitPhase && - flushPendingDiscreteUpdates(); +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); }; var roots = new Map(), ReactNativeRenderer = { @@ -7021,6 +7775,14 @@ var roots = new Map(), })(React.Component); })(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + }, setNativeProps: function(handle, nativeProps) { null != handle._nativeTag && ((nativeProps = diffProperties( @@ -7039,7 +7801,7 @@ var roots = new Map(), render: function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = new FiberRootNode(containerTag, !1); + root = new FiberRootNode(containerTag, 0, !1); var uninitializedFiber = createFiber(3, null, null, 0); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -7196,7 +7958,8 @@ var roots = new Map(), findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, - setRefreshHandler: null + setRefreshHandler: null, + getCurrentFiber: null }) ); })({ diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 0ba66216d52a0f..2d278cf341ea20 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -15,10 +15,9 @@ var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/R React = require("react"), Scheduler = require("scheduler"), tracing = require("scheduler/tracing"); -function ReactError(message) { - message = Error(message); - message.name = "Invariant Violation"; - return message; +function ReactError(error) { + error.name = "Invariant Violation"; + return error; } var eventPluginOrder = null, namesToPlugins = {}; @@ -29,16 +28,20 @@ function recomputePluginOrdering() { pluginIndex = eventPluginOrder.indexOf(pluginName); if (!(-1 < pluginIndex)) throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); if (!plugins[pluginIndex]) { if (!pluginModule.extractEvents) throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); plugins[pluginIndex] = pluginModule; pluginIndex = pluginModule.eventTypes; @@ -49,9 +52,11 @@ function recomputePluginOrdering() { eventName$jscomp$0 = eventName; if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ) ); eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -77,11 +82,13 @@ function recomputePluginOrdering() { : (JSCompiler_inline_result = !1); if (!JSCompiler_inline_result) throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } } @@ -90,9 +97,11 @@ function recomputePluginOrdering() { function publishRegistrationName(registrationName, pluginModule) { if (registrationNameModules[registrationName]) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); registrationNameModules[registrationName] = pluginModule; } @@ -141,7 +150,9 @@ function invokeGuardedCallbackAndCatchFirstError( caughtError = null; } else throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } @@ -159,7 +170,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; if (Array.isArray(dispatchListener)) - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null; @@ -172,7 +183,9 @@ function executeDirectDispatch(event) { function accumulateInto(current, next) { if (null == next) throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); if (null == current) return next; if (Array.isArray(current)) { @@ -209,7 +222,9 @@ var injection = { injectEventPluginOrder: function(injectedEventPluginOrder) { if (eventPluginOrder) throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); @@ -226,9 +241,11 @@ var injection = { ) { if (namesToPlugins[pluginName]) throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); namesToPlugins[pluginName] = pluginModule; isOrderingDirty = !0; @@ -270,11 +287,13 @@ function getListener(inst, registrationName) { if (inst) return null; if (listener && "function" !== typeof listener) throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); return listener; } @@ -438,7 +457,9 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { if (!(event instanceof this)) throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); event.destructor(); 10 > this.eventPool.length && this.eventPool.push(event); @@ -474,7 +495,8 @@ function timestampForTouch(touch) { } function getTouchIdentifier(_ref) { _ref = _ref.identifier; - if (null == _ref) throw ReactError("Touch object is missing identifier."); + if (null == _ref) + throw ReactError(Error("Touch object is missing identifier.")); return _ref; } function recordTouchStart(touch) { @@ -517,7 +539,7 @@ function recordTouchMove(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch move without a touch start.\nTouch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -535,7 +557,7 @@ function recordTouchEnd(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch end without a touch start.\nTouch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -589,7 +611,7 @@ var ResponderTouchHistoryStore = { function accumulate(current, next) { if (null == next) throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error("accumulate(...): Accumulated items must not be null or undefined.") ); return null == current ? next @@ -967,7 +989,9 @@ injection.injectEventPluginsByName({ directDispatchConfig = customDirectEventTypes[topLevelType]; if (!bubbleDispatchConfig && !directDispatchConfig) throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); topLevelType = SyntheticEvent.getPooled( bubbleDispatchConfig || directDispatchConfig, @@ -984,33 +1008,39 @@ injection.injectEventPluginsByName({ } } }); -var instanceCache = {}, - instanceProps = {}; +var instanceCache = new Map(), + instanceProps = new Map(); function getInstanceFromTag(tag) { - return instanceCache[tag] || null; + return instanceCache.get(tag) || null; } var restoreTarget = null, restoreQueue = null; function restoreStateOfTarget(target) { if (getInstanceFromNode(target)) throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } -function _batchedUpdatesImpl(fn, bookkeeping) { +require("../shims/ReactFeatureFlags"); +function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } -function _flushInteractiveUpdatesImpl() {} -var isBatching = !1; +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { - if (isBatching) return fn(bookkeeping); - isBatching = !0; + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - if (((isBatching = !1), null !== restoreTarget || null !== restoreQueue)) + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) if ( - (_flushInteractiveUpdatesImpl(), + (flushDiscreteUpdatesImpl(), restoreTarget && ((bookkeeping = restoreTarget), (fn = restoreQueue), @@ -1047,7 +1077,9 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); if (eventQueue) throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); if (hasRethrowError) throw ((events = rethrowError), @@ -1095,13 +1127,13 @@ ReactNativePrivateInterface.RCTEventEmitter.register({ } }); getFiberCurrentPropsFromNode = function(stateNode) { - return instanceProps[stateNode._nativeTag] || null; + return instanceProps.get(stateNode._nativeTag) || null; }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { var tag = inst.stateNode._nativeTag; void 0 === tag && (tag = inst.stateNode.canonical._nativeTag); - if (!tag) throw ReactError("All native instances should have a tag."); + if (!tag) throw ReactError(Error("All native instances should have a tag.")); return tag; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1118,6 +1150,8 @@ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher") || (ReactSharedInternals.ReactCurrentDispatcher = { current: null }); +ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig") || + (ReactSharedInternals.ReactCurrentBatchConfig = { suspense: null }); var hasSymbol = "function" === typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, @@ -1131,11 +1165,13 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, + REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; -hasSymbol && Symbol.for("react.event_component"); -hasSymbol && Symbol.for("react.event_target"); -hasSymbol && Symbol.for("react.event_target.touch_hit"); +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; @@ -1144,14 +1180,11 @@ function getIteratorFn(maybeIterable) { maybeIterable["@@iterator"]; return "function" === typeof maybeIterable ? maybeIterable : null; } -require("../shims/ReactFeatureFlags"); function getComponentName(type) { if (null == type) return null; if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -1162,6 +1195,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1196,14 +1231,14 @@ function isFiberMountedImpl(fiber) { } function assertIsMounted(fiber) { if (2 !== isFiberMountedImpl(fiber)) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; if (!alternate) { alternate = isFiberMountedImpl(fiber); if (3 === alternate) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return 1 === alternate ? null : fiber; } for (var a = fiber, b = alternate; ; ) { @@ -1224,7 +1259,7 @@ function findCurrentFiberUsingSlowPath(fiber) { if (parentB === b) return assertIsMounted(parentA), alternate; parentB = parentB.sibling; } - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } if (a.return !== b.return) (a = parentA), (b = parentB); else { @@ -1261,17 +1296,21 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (!didFindChild) throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } } if (a.alternate !== b) throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (3 !== a.tag) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return a.stateNode.current === a ? fiber : alternate; } function findCurrentHostFiber(parent) { @@ -1586,7 +1625,9 @@ var ReactNativeFiberHostComponent = (function() { })(); function shim$1() { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } var getViewConfigForType = @@ -1601,11 +1642,11 @@ function allocateTag() { } function recursivelyUncacheFiberNode(node) { if ("number" === typeof node) - delete instanceCache[node], delete instanceProps[node]; + instanceCache.delete(node), instanceProps.delete(node); else { var tag = node._nativeTag; - delete instanceCache[tag]; - delete instanceProps[tag]; + instanceCache.delete(tag); + instanceProps.delete(tag); node._children.forEach(recursivelyUncacheFiberNode); } } @@ -1621,8 +1662,22 @@ function finalizeInitialChildren(parentInstance) { return !1; } var scheduleTimeout = setTimeout, - cancelTimeout = clearTimeout, - BEFORE_SLASH_RE = /^(.*)[\\\/]/; + cancelTimeout = clearTimeout; +function removeChild(parentInstance, child) { + recursivelyUncacheFiberNode(child); + var children = parentInstance._children; + child = children.indexOf(child); + children.splice(child, 1); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, + [], + [], + [], + [], + [child] + ); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; function getStackByFiberInDevAndProd(workInProgress) { var info = ""; do { @@ -1708,7 +1763,9 @@ function popTopLevelContextObject(fiber) { function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); @@ -1721,10 +1778,12 @@ function processChildContext(fiber, type, parentContext) { for (var contextKey in instance) if (!(contextKey in fiber)) throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); return Object.assign({}, parentContext, instance); } @@ -1746,7 +1805,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { var instance = workInProgress.stateNode; if (!instance) throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); didChange ? ((type = processChildContext(workInProgress, type, previousContext)), @@ -1757,40 +1818,11 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -var onCommitFiberRoot = null, - onCommitFiberUnmount = null; -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) {} - }; -} -var isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; -function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - var rendererID = hook.inject(internals); - onCommitFiberRoot = catchErrors(function(root) { - hook.onCommitFiberRoot( - rendererID, - root, - void 0, - 64 === (root.current.effectTag & 64) - ); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) {} - return !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 = Scheduler.unstable_now, Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel, @@ -1804,12 +1836,16 @@ if ( null == tracing.__interactionsRef.current ) throw ReactError( - "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 http://fb.me/react-profiling" + 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 http://fb.me/react-profiling" + ) ); var fakeCallbackNode = {}, - immediateQueue = null, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, immediateQueueCallbackNode = null, - isFlushingImmediate = !1, + isFlushingSyncQueue = !1, initialTimeMs = Scheduler_now(), now = 1e4 > initialTimeMs @@ -1830,7 +1866,7 @@ function getCurrentPriorityLevel() { case Scheduler_IdlePriority: return 95; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function reactPriorityToSchedulerPriority(reactPriorityLevel) { @@ -1846,7 +1882,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case 95: return Scheduler_IdlePriority; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function runWithPriority(reactPriorityLevel, fn) { @@ -1854,46 +1890,47 @@ function runWithPriority(reactPriorityLevel, fn) { return Scheduler_runWithPriority(reactPriorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (99 === reactPriorityLevel) - return ( - null === immediateQueue - ? ((immediateQueue = [callback]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ))) - : immediateQueue.push(callback), - fakeCallbackNode - ); reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function flushImmediateQueue() { +function scheduleSyncCallback(callback) { + null === syncQueue + ? ((syncQueue = [callback]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(callback); + return fakeCallbackNode; +} +function flushSyncCallbackQueue() { null !== immediateQueueCallbackNode && Scheduler_cancelCallback(immediateQueueCallbackNode); - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && null !== immediateQueue) { - isFlushingImmediate = !0; +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; var i = 0; try { - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do callback = callback(!0); - while (null !== callback); - } - immediateQueue = null; + 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 !== immediateQueue && - (immediateQueue = immediateQueue.slice(i + 1)), + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ), error); } finally { - isFlushingImmediate = !1; + isFlushingSyncQueue = !1; } } } @@ -1901,7 +1938,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (1073741823 === expirationTime) return 99; if (1 === expirationTime) return 95; currentTime = - 10 * (1073741822 - expirationTime) - 10 * (1073741822 - currentTime); + 10 * (1073741821 - expirationTime) - 10 * (1073741821 - currentTime); return 0 >= currentTime ? 99 : 250 >= currentTime @@ -1983,7 +2020,7 @@ var valueCursor = { current: null }, currentlyRenderingFiber = null, lastContextDependency = null, lastContextWithAllBitsObserved = null; -function resetContextDependences() { +function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } function pushProvider(providerFiber, nextValue) { @@ -1996,14 +2033,32 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); providerFiber.type._context._currentValue = currentValue; } +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + for (; null !== parent; ) { + var alternate = parent.alternate; + if (parent.childExpirationTime < renderExpirationTime) + (parent.childExpirationTime = renderExpirationTime), + null !== alternate && + alternate.childExpirationTime < renderExpirationTime && + (alternate.childExpirationTime = renderExpirationTime); + else if ( + null !== alternate && + alternate.childExpirationTime < renderExpirationTime + ) + alternate.childExpirationTime = renderExpirationTime; + else break; + parent = parent.return; + } +} function prepareToReadContext(workInProgress, renderExpirationTime) { currentlyRenderingFiber = workInProgress; lastContextWithAllBitsObserved = lastContextDependency = null; - var currentDependencies = workInProgress.contextDependencies; - null !== currentDependencies && - currentDependencies.expirationTime >= renderExpirationTime && - (didReceiveUpdate = !0); - workInProgress.contextDependencies = null; + workInProgress = workInProgress.dependencies; + null !== workInProgress && + null !== workInProgress.firstContext && + (workInProgress.expirationTime >= renderExpirationTime && + (didReceiveUpdate = !0), + (workInProgress.firstContext = null)); } function readContext(context, observedBits) { if ( @@ -2017,12 +2072,16 @@ function readContext(context, observedBits) { if (null === lastContextDependency) { if (null === currentlyRenderingFiber) throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); lastContextDependency = observedBits; - currentlyRenderingFiber.contextDependencies = { - first: observedBits, - expirationTime: 0 + currentlyRenderingFiber.dependencies = { + expirationTime: 0, + firstContext: observedBits, + listeners: null, + responders: null }; } else lastContextDependency = lastContextDependency.next = observedBits; } @@ -2055,9 +2114,10 @@ function cloneUpdateQueue(currentQueue) { lastCapturedEffect: null }; } -function createUpdate(expirationTime) { +function createUpdate(expirationTime, suspenseConfig) { return { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, @@ -2173,8 +2233,10 @@ function processUpdateQueue( ((newFirstUpdate = update), (newBaseState = resultState)), newExpirationTime < updateExpirationTime && (newExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), (resultState = getStateFromUpdate( workInProgress, queue, @@ -2250,15 +2312,18 @@ function commitUpdateEffects(effect, instance) { var context = instance; if ("function" !== typeof _callback3) throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - _callback3 + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + _callback3 + ) ); _callback3.call(context); } effect = effect.nextEffect; } } -var emptyRefsObject = new React.Component().refs; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + emptyRefsObject = new React.Component().refs; function applyDerivedStateFromProps( workInProgress, ctor, @@ -2285,36 +2350,42 @@ var classComponentUpdater = { }, enqueueSetState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 1; + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 2; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 2; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); } }; @@ -2443,15 +2514,19 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); inst = element.stateNode; } if (!inst) throw ReactError( - "Missing owner for string ref " + - returnFiber + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + returnFiber + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); var stringRef = "" + returnFiber; if ( @@ -2471,13 +2546,17 @@ function coerceRef(returnFiber, current$$1, element) { } if ("string" !== typeof returnFiber) throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); if (!element._owner) throw ReactError( - "Element ref was specified as a string (" + - returnFiber + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + returnFiber + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } return returnFiber; @@ -2485,11 +2564,13 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) throw ReactError( - "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === Object.prototype.toString.call(newChild) + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + ) ); } function ChildReconciler(shouldTrackSideEffects) { @@ -2892,11 +2973,13 @@ function ChildReconciler(shouldTrackSideEffects) { var iteratorFn = getIteratorFn(newChildrenIterable); if ("function" !== typeof iteratorFn) throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); newChildrenIterable = iteratorFn.call(newChildrenIterable); if (null == newChildrenIterable) - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); for ( var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, @@ -3131,8 +3214,10 @@ function ChildReconciler(shouldTrackSideEffects) { case 0: throw ((returnFiber = returnFiber.type), ReactError( - (returnFiber.displayName || returnFiber.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (returnFiber.displayName || returnFiber.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) )); } return deleteRemainingChildren(returnFiber, currentFirstChild); @@ -3147,7 +3232,9 @@ var reconcileChildFibers = ChildReconciler(!0), function requiredContext(c) { if (c === NO_CONTEXT) throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); return c; } @@ -3185,6 +3272,50 @@ function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } +var SubtreeSuspenseContextMask = 1, + InvisibleParentSuspenseContext = 1, + ForceSuspenseFallback = 2, + suspenseStackCursor = { current: 0 }; +function findFirstSuspended(row) { + for (var node = row; null !== node; ) { + if (13 === node.tag) { + if (null !== node.memoizedState) return node; + } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { + if (0 !== (node.effectTag & 64)) return node; + } else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; +} +var currentListenerHookIndex = 0; +function updateListenerHook(responder, props) { + var dependencies = null.dependencies; + null === dependencies && + (dependencies = null.dependencies = { + expirationTime: 0, + firstContext: null, + listeners: [], + responders: null + }); + var listeners = dependencies.listeners; + null === listeners && (dependencies.listeners = listeners = []); + listeners.length === currentListenerHookIndex + ? (listeners.push({ responder: responder, props: props }), + currentListenerHookIndex++) + : ((listeners = listeners[currentListenerHookIndex++]), + (listeners.responder = responder), + (listeners.props = props)); +} var NoEffect$1 = 0, UnmountSnapshot = 2, UnmountMutation = 4, @@ -3209,7 +3340,9 @@ var NoEffect$1 = 0, numberOfReRenders = 0; function throwInvalidHookError() { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } function areHookInputsEqual(nextDeps, prevDeps) { @@ -3259,7 +3392,9 @@ function renderWithHooks( sideEffectTag = 0; if (current) throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); return workInProgress; } @@ -3295,7 +3430,9 @@ function updateWorkInProgressHook() { (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) - throw ReactError("Rendered more hooks than during the previous render."); + throw ReactError( + Error("Rendered more hooks than during the previous render.") + ); currentHook = nextCurrentHook; var newHook = { memoizedState: currentHook.memoizedState, @@ -3320,7 +3457,9 @@ function updateReducer(reducer) { queue = hook.queue; if (null === queue) throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); queue.lastRenderedReducer = reducer; if (0 < numberOfReRenders) { @@ -3363,8 +3502,10 @@ function updateReducer(reducer) { (firstRenderPhaseUpdate = newState)), updateExpirationTime > remainingExpirationTime && (remainingExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ), (newState = _update.eagerReducer === reducer ? _update.eagerState @@ -3443,7 +3584,9 @@ function mountDebugValue() {} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); var alternate = fiber.alternate; if ( @@ -3454,6 +3597,7 @@ function dispatchAction(fiber, queue, action) { ((didScheduleRenderPhaseUpdate = !0), (fiber = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, @@ -3469,24 +3613,29 @@ function dispatchAction(fiber, queue, action) { queue.next = fiber; } else { - flushPassiveEffects(); - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, fiber); - var _update2 = { - expirationTime: currentTime, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }, - _last = queue.last; - if (null === _last) _update2.next = _update2; + var currentTime = requestCurrentTime(), + _suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); + _suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: _suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var _last = queue.last; + if (null === _last) _suspenseConfig.next = _suspenseConfig; else { var first = _last.next; - null !== first && (_update2.next = first); - _last.next = _update2; + null !== first && (_suspenseConfig.next = first); + _last.next = _suspenseConfig; } - queue.last = _update2; + queue.last = _suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3495,8 +3644,8 @@ function dispatchAction(fiber, queue, action) { try { var currentState = queue.lastRenderedState, _eagerState = alternate(currentState, action); - _update2.eagerReducer = alternate; - _update2.eagerState = _eagerState; + _suspenseConfig.eagerReducer = alternate; + _suspenseConfig.eagerState = _eagerState; if (is(_eagerState, currentState)) return; } catch (error) { } finally { @@ -3515,7 +3664,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3588,7 +3738,8 @@ var ContextOnlyDispatcher = { ); return [hook.memoizedState, initialState]; }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, HooksDispatcherOnUpdate = { readContext: readContext, @@ -3642,7 +3793,8 @@ var ContextOnlyDispatcher = { useState: function(initialState) { return updateReducer(basicStateReducer, initialState); }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -4198,6 +4350,7 @@ function pushHostRootContext(workInProgress) { pushTopLevelContextObject(workInProgress, root.context, !1); pushHostContainer(workInProgress, root.containerInfo); } +var SUSPENDED_MARKER = {}; function updateSuspenseComponent( current$$1, workInProgress, @@ -4205,35 +4358,50 @@ function updateSuspenseComponent( ) { var mode = workInProgress.mode, nextProps = workInProgress.pendingProps, - nextState = workInProgress.memoizedState; - if (0 === (workInProgress.effectTag & 64)) { - nextState = null; - var nextDidTimeout = !1; - } else - (nextState = { - fallbackExpirationTime: - null !== nextState ? nextState.fallbackExpirationTime : 0 - }), + suspenseContext = suspenseStackCursor.current, + nextState = null, + nextDidTimeout = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || + (JSCompiler_temp = + 0 !== (suspenseContext & ForceSuspenseFallback) && + (null === current$$1 || null !== current$$1.memoizedState)); + JSCompiler_temp + ? ((nextState = SUSPENDED_MARKER), (nextDidTimeout = !0), - (workInProgress.effectTag &= -65); + (workInProgress.effectTag &= -65)) + : (null !== current$$1 && null === current$$1.memoizedState) || + void 0 === nextProps.fallback || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= InvisibleParentSuspenseContext); + suspenseContext &= SubtreeSuspenseContextMask; + push(suspenseStackCursor, suspenseContext, workInProgress); if (null === current$$1) if (nextDidTimeout) { - var nextFallbackChildren = nextProps.fallback; + nextProps = nextProps.fallback; current$$1 = createFiberFromFragment(null, mode, 0, null); - 0 === (workInProgress.mode & 1) && - (current$$1.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child); + current$$1.return = workInProgress; + if (0 === (workInProgress.mode & 2)) + for ( + nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + current$$1.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = current$$1), + (nextDidTimeout = nextDidTimeout.sibling); renderExpirationTime = createFiberFromFragment( - nextFallbackChildren, + nextProps, mode, renderExpirationTime, null ); + renderExpirationTime.return = workInProgress; current$$1.sibling = renderExpirationTime; mode = current$$1; - mode.return = renderExpirationTime.return = workInProgress; } else mode = renderExpirationTime = mountChildFibers( workInProgress, @@ -4244,95 +4412,235 @@ function updateSuspenseComponent( else { if (null !== current$$1.memoizedState) if ( - ((nextFallbackChildren = current$$1.child), - (mode = nextFallbackChildren.sibling), + ((suspenseContext = current$$1.child), + (mode = suspenseContext.sibling), nextDidTimeout) ) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - nextFallbackChildren, - nextFallbackChildren.pendingProps, + suspenseContext, + suspenseContext.pendingProps, 0 ); - 0 === (workInProgress.mode & 1) && + renderExpirationTime.return = workInProgress; + if ( + 0 === (workInProgress.mode & 2) && ((nextDidTimeout = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== nextFallbackChildren.child && - (renderExpirationTime.child = nextDidTimeout)); - if (workInProgress.mode & 4) { - nextFallbackChildren = 0; + nextDidTimeout !== suspenseContext.child) + ) for ( - nextDidTimeout = renderExpirationTime.child; + renderExpirationTime.child = nextDidTimeout; null !== nextDidTimeout; ) - (nextFallbackChildren += nextDidTimeout.treeBaseDuration), + (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - renderExpirationTime.treeBaseDuration = nextFallbackChildren; + if (workInProgress.mode & 8) { + nextDidTimeout = 0; + for ( + suspenseContext = renderExpirationTime.child; + null !== suspenseContext; + + ) + (nextDidTimeout += suspenseContext.treeBaseDuration), + (suspenseContext = suspenseContext.sibling); + renderExpirationTime.treeBaseDuration = nextDidTimeout; } - nextFallbackChildren = renderExpirationTime.sibling = createWorkInProgress( - mode, - nextProps, - mode.expirationTime - ); + nextProps = createWorkInProgress(mode, nextProps, mode.expirationTime); + nextProps.return = workInProgress; + renderExpirationTime.sibling = nextProps; mode = renderExpirationTime; renderExpirationTime.childExpirationTime = 0; - renderExpirationTime = nextFallbackChildren; - mode.return = renderExpirationTime.return = workInProgress; + renderExpirationTime = nextProps; } else mode = renderExpirationTime = reconcileChildFibers( workInProgress, - nextFallbackChildren.child, + suspenseContext.child, nextProps.children, renderExpirationTime ); - else { - var _currentPrimaryChild = current$$1.child; - if (nextDidTimeout) { - nextProps = nextProps.fallback; - nextFallbackChildren = createFiberFromFragment(null, mode, 0, null); - nextFallbackChildren.child = _currentPrimaryChild; - 0 === (workInProgress.mode & 1) && - (nextFallbackChildren.child = + else if (((suspenseContext = current$$1.child), nextDidTimeout)) { + nextDidTimeout = nextProps.fallback; + nextProps = createFiberFromFragment(null, mode, 0, null); + nextProps.return = workInProgress; + nextProps.child = suspenseContext; + null !== suspenseContext && (suspenseContext.return = nextProps); + if (0 === (workInProgress.mode & 2)) + for ( + suspenseContext = null !== workInProgress.memoizedState ? workInProgress.child.child - : workInProgress.child); - if (workInProgress.mode & 4) { - nextDidTimeout = 0; - for ( - _currentPrimaryChild = nextFallbackChildren.child; - null !== _currentPrimaryChild; + : workInProgress.child, + nextProps.child = suspenseContext; + null !== suspenseContext; + ) + (suspenseContext.return = nextProps), + (suspenseContext = suspenseContext.sibling); + if (workInProgress.mode & 8) { + suspenseContext = 0; + for (JSCompiler_temp = nextProps.child; null !== JSCompiler_temp; ) + (suspenseContext += JSCompiler_temp.treeBaseDuration), + (JSCompiler_temp = JSCompiler_temp.sibling); + nextProps.treeBaseDuration = suspenseContext; + } + renderExpirationTime = createFiberFromFragment( + nextDidTimeout, + mode, + renderExpirationTime, + null + ); + renderExpirationTime.return = workInProgress; + nextProps.sibling = renderExpirationTime; + renderExpirationTime.effectTag |= 2; + mode = nextProps; + nextProps.childExpirationTime = 0; + } else + renderExpirationTime = mode = reconcileChildFibers( + workInProgress, + suspenseContext, + nextProps.children, + renderExpirationTime + ); + workInProgress.stateNode = current$$1.stateNode; + } + workInProgress.memoizedState = nextState; + workInProgress.child = mode; + return renderExpirationTime; +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailExpiration = 0), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren( + current$$1, + workInProgress, + nextProps.children, + renderExpirationTime + ); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & ForceSuspenseFallback)) + (nextProps = + (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), + (workInProgress.effectTag |= 64); + else { + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) { + if (null !== current$$1.memoizedState) { + current$$1.expirationTime < renderExpirationTime && + (current$$1.expirationTime = renderExpirationTime); + var alternate = current$$1.alternate; + null !== alternate && + alternate.expirationTime < renderExpirationTime && + (alternate.expirationTime = renderExpirationTime); + scheduleWorkOnParentPath(current$$1.return, renderExpirationTime); + } + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress ) - (nextDidTimeout += _currentPrimaryChild.treeBaseDuration), - (_currentPrimaryChild = _currentPrimaryChild.sibling); - nextFallbackChildren.treeBaseDuration = nextDidTimeout; + break a; + current$$1 = current$$1.return; } - renderExpirationTime = nextFallbackChildren.sibling = createFiberFromFragment( - nextProps, - mode, + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + nextProps &= SubtreeSuspenseContextMask; + } + push(suspenseStackCursor, nextProps, workInProgress); + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderExpirationTime = workInProgress.child; + for (revealOrder = null; null !== renderExpirationTime; ) + (nextProps = renderExpirationTime.alternate), + null !== nextProps && + null === findFirstSuspended(nextProps) && + (revealOrder = renderExpirationTime), + (renderExpirationTime = renderExpirationTime.sibling); + renderExpirationTime = revealOrder; + null === renderExpirationTime + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderExpirationTime.sibling), + (renderExpirationTime.sibling = null)); + initSuspenseListRenderState( + workInProgress, + !1, + revealOrder, renderExpirationTime, - null + tailMode ); - renderExpirationTime.effectTag |= 2; - mode = nextFallbackChildren; - nextFallbackChildren.childExpirationTime = 0; - mode.return = renderExpirationTime.return = workInProgress; - } else - renderExpirationTime = mode = reconcileChildFibers( + break; + case "backwards": + renderExpirationTime = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + nextProps = revealOrder.alternate; + if (null !== nextProps && null === findFirstSuspended(nextProps)) { + workInProgress.child = revealOrder; + break; + } + nextProps = revealOrder.sibling; + revealOrder.sibling = renderExpirationTime; + renderExpirationTime = revealOrder; + revealOrder = nextProps; + } + initSuspenseListRenderState( workInProgress, - _currentPrimaryChild, - nextProps.children, - renderExpirationTime + !0, + renderExpirationTime, + null, + tailMode ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; } - workInProgress.stateNode = current$$1.stateNode; - } - workInProgress.memoizedState = nextState; - workInProgress.child = mode; - return renderExpirationTime; + return workInProgress.child; } function bailoutOnAlreadyFinishedWork( current$$1, @@ -4340,11 +4648,11 @@ function bailoutOnAlreadyFinishedWork( renderExpirationTime ) { null !== current$$1 && - (workInProgress.contextDependencies = current$$1.contextDependencies); + (workInProgress.dependencies = current$$1.dependencies); profilerStartTime = -1; if (workInProgress.childExpirationTime < renderExpirationTime) return null; if (null !== current$$1 && workInProgress.child !== current$$1.child) - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); if (null !== workInProgress.child) { current$$1 = workInProgress.child; renderExpirationTime = createWorkInProgress( @@ -4376,6 +4684,7 @@ var appendAllChildren = void 0, appendAllChildren = function(parent, workInProgress) { for (var node = workInProgress.child; null !== node; ) { if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); + else if (20 === node.tag) parent._children.push(node.stateNode.instance); else if (4 !== node.tag && null !== node.child) { node.child.return = node; node = node.child; @@ -4400,6 +4709,30 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { updateHostText$1 = function(current, workInProgress, oldText, newText) { oldText !== newText && (workInProgress.effectTag |= 4); }; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var _lastTailNode = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === _lastTailNode + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (_lastTailNode.sibling = null); + } +} function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4426,22 +4759,24 @@ function completeWork(current, workInProgress, renderExpirationTime) { break; case 5: popHostContext(workInProgress); - renderExpirationTime = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - type, + renderExpirationTime, newProps, - renderExpirationTime + rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); else if (newProps) { current = requiredContext(contextStackCursor$1.current); var tag = allocateTag(), - viewConfig = getViewConfigForType(type), + viewConfig = getViewConfigForType(renderExpirationTime), updatePayload = diffProperties( null, emptyObject, @@ -4451,25 +4786,27 @@ function completeWork(current, workInProgress, renderExpirationTime) { ReactNativePrivateInterface.UIManager.createView( tag, viewConfig.uiViewClassName, - renderExpirationTime, + rootContainerInstance, updatePayload ); viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); - instanceCache[tag] = workInProgress; - instanceProps[tag] = newProps; + instanceCache.set(tag, workInProgress); + instanceProps.set(tag, newProps); appendAllChildren(viewConfig, workInProgress, !1, !1); finalizeInitialChildren( viewConfig, - type, - newProps, renderExpirationTime, + newProps, + rootContainerInstance, current ) && (workInProgress.effectTag |= 4); workInProgress.stateNode = viewConfig; null !== workInProgress.ref && (workInProgress.effectTag |= 128); } else if (null === workInProgress.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -4483,57 +4820,65 @@ function completeWork(current, workInProgress, renderExpirationTime) { else { if ("string" !== typeof newProps && null === workInProgress.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); current = requiredContext(rootInstanceStackCursor.current); if (!requiredContext(contextStackCursor$1.current).isInAParentText) throw ReactError( - "Text strings must be rendered within a component." + Error("Text strings must be rendered within a component.") ); - renderExpirationTime = allocateTag(); + rootContainerInstance = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - renderExpirationTime, + rootContainerInstance, "RCTRawText", current, { text: newProps } ); - instanceCache[renderExpirationTime] = workInProgress; - workInProgress.stateNode = renderExpirationTime; + instanceCache.set(rootContainerInstance, workInProgress); + workInProgress.stateNode = rootContainerInstance; } break; case 11: break; case 13: + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( (workInProgress.expirationTime = renderExpirationTime), workInProgress ); newProps = null !== newProps; - renderExpirationTime = !1; + rootContainerInstance = !1; null !== current && - ((type = current.memoizedState), - (renderExpirationTime = null !== type), + ((renderExpirationTime = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime), newProps || - null === type || - ((type = type.fallbackExpirationTime), - type < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = type), - (current = current.child.sibling), - null !== current && - ((type = workInProgress.firstEffect), - null !== type - ? ((workInProgress.firstEffect = current), - (current.nextEffect = type)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = current), - (current.nextEffect = null)), - (current.effectTag = 8)))); - newProps && - !renderExpirationTime && - 0 !== (workInProgress.mode & 1) && - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - if (newProps || renderExpirationTime) workInProgress.effectTag |= 4; + null === renderExpirationTime || + ((renderExpirationTime = current.child.sibling), + null !== renderExpirationTime && + ((tag = workInProgress.firstEffect), + null !== tag + ? ((workInProgress.firstEffect = renderExpirationTime), + (renderExpirationTime.nextEffect = tag)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), + (renderExpirationTime.nextEffect = null)), + (renderExpirationTime.effectTag = 8)))); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & InvisibleParentSuspenseContext) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; break; case 7: break; @@ -4558,60 +4903,231 @@ function completeWork(current, workInProgress, renderExpirationTime) { case 18: break; case 19: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (null === newProps) break; + rootContainerInstance = 0 !== (workInProgress.effectTag & 64); + tag = newProps.rendering; + if (null === tag) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = workInProgress.child; null !== current; ) { + tag = findFirstSuspended(current); + if (null !== tag) { + workInProgress.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = tag.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + workInProgress.firstEffect = workInProgress.lastEffect = null; + current = renderExpirationTime; + for (newProps = workInProgress.child; null !== newProps; ) + (rootContainerInstance = newProps), + (tag = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (renderExpirationTime = rootContainerInstance.alternate), + null === renderExpirationTime + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = tag), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null), + (rootContainerInstance.selfBaseDuration = 0), + (rootContainerInstance.treeBaseDuration = 0)) + : ((rootContainerInstance.childExpirationTime = + renderExpirationTime.childExpirationTime), + (rootContainerInstance.expirationTime = + renderExpirationTime.expirationTime), + (rootContainerInstance.child = + renderExpirationTime.child), + (rootContainerInstance.memoizedProps = + renderExpirationTime.memoizedProps), + (rootContainerInstance.memoizedState = + renderExpirationTime.memoizedState), + (rootContainerInstance.updateQueue = + renderExpirationTime.updateQueue), + (tag = renderExpirationTime.dependencies), + (rootContainerInstance.dependencies = + null === tag + ? null + : { + expirationTime: tag.expirationTime, + firstContext: tag.firstContext, + listeners: tag.listeners, + responders: tag.responders + }), + (rootContainerInstance.selfBaseDuration = + renderExpirationTime.selfBaseDuration), + (rootContainerInstance.treeBaseDuration = + renderExpirationTime.treeBaseDuration)), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & SubtreeSuspenseContextMask) | + ForceSuspenseFallback, + workInProgress + ); + return workInProgress.child; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if (((current = findFirstSuspended(tag)), null !== current)) { + if ( + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && "hidden" === newProps.tailMode) + ) { + current = current.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + workInProgress = workInProgress.lastEffect = newProps.lastEffect; + null !== workInProgress && (workInProgress.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime && + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (current = renderExpirationTime - 1), + (workInProgress.expirationTime = workInProgress.childExpirationTime = current), + null === spawnedWorkDuringRender + ? (spawnedWorkDuringRender = [current]) + : spawnedWorkDuringRender.push(current)); + newProps.isBackwards + ? ((tag.sibling = workInProgress.child), (workInProgress.child = tag)) + : ((current = newProps.last), + null !== current + ? (current.sibling = tag) + : (workInProgress.child = tag), + (newProps.last = tag)); + } + if (null !== newProps.tail) + return ( + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500), + (current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (current.sibling = null), + (newProps = suspenseStackCursor.current), + (newProps = rootContainerInstance + ? (newProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback + : newProps & SubtreeSuspenseContextMask), + push(suspenseStackCursor, newProps, workInProgress), + current + ); break; case 20: break; default: throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } return null; } -function createCapturedValue(value, source) { - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} -function logCapturedError(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - if (error instanceof Error) { - capturedError = error.message; - var name = error.name; - try { - error.message = - (capturedError ? name + ": " + capturedError : name) + - "\n\nThis error is located at:" + - componentStack; - } catch (e) {} - } else - error = - "string" === typeof error - ? Error(error + "\n\nThis error is located at:" + componentStack) - : Error("Unspecified error at:" + componentStack); - ReactNativePrivateInterface.ExceptionsManager.handleException(error, !1); -} -var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; -function logError(boundary, errorInfo) { - var source = errorInfo.source, - stack = errorInfo.stack; - null === stack && - null !== source && - (stack = getStackByFiberInDevAndProd(source)); - errorInfo = { - componentName: null !== source ? getComponentName(source.type) : null, - componentStack: null !== stack ? stack : "", - error: errorInfo.value, - errorBoundary: null, - errorBoundaryName: null, - errorBoundaryFound: !1, - willRetry: !1 - }; - null !== boundary && - 1 === boundary.tag && +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + workInProgress.effectTag = (effectTag & -2049) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null + ); + case 18: + return null; + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} +function createCapturedValue(value, source) { + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") + ); +function logCapturedError(capturedError) { + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ) && console.error(capturedError.error); +} +var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; +function logError(boundary, errorInfo) { + var source = errorInfo.source, + stack = errorInfo.stack; + null === stack && + null !== source && + (stack = getStackByFiberInDevAndProd(source)); + errorInfo = { + componentName: null !== source ? getComponentName(source.type) : null, + componentStack: null !== stack ? stack : "", + error: errorInfo.value, + errorBoundary: null, + errorBoundaryName: null, + errorBoundaryFound: !1, + willRetry: !1 + }; + null !== boundary && + 1 === boundary.tag && ((errorInfo.errorBoundary = boundary.stateNode), (errorInfo.errorBoundaryName = getComponentName(boundary.type)), (errorInfo.errorBoundaryFound = !0), @@ -4652,64 +5168,6 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } -function hideOrUnhideAllChildren(finishedWork, isHidden) { - for (var node = finishedWork; ; ) { - if (5 === node.tag) { - var instance = node.stateNode; - if (isHidden) { - var viewConfig = instance.viewConfig; - var updatePayload = diffProperties( - null, - emptyObject, - { style: { display: "none" } }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } else { - instance = node.stateNode; - updatePayload = node.memoizedProps; - viewConfig = instance.viewConfig; - var prevProps = Object.assign({}, updatePayload, { - style: [updatePayload.style, { display: "none" }] - }); - updatePayload = diffProperties( - null, - prevProps, - updatePayload, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } - } else { - if (6 === node.tag) throw Error("Not yet implemented."); - if (13 === node.tag && null !== node.memoizedState) { - instance = node.child.sibling; - instance.return = node; - node = instance; - continue; - } else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - } - if (node === finishedWork) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === finishedWork) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -} function commitUnmount(current$$1$jscomp$0) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -4757,6 +5215,20 @@ function commitUnmount(current$$1$jscomp$0) { unmountHostComponents(current$$1$jscomp$0); } } +function commitNestedUnmounts(root) { + for (var node = root; ; ) + if ((commitUnmount(node), null !== node.child && 4 !== node.tag)) + (node.child.return = node), (node = node.child); + else { + if (node === root) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === root) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} function isHostParent(fiber) { return 5 === fiber.tag || 3 === fiber.tag || 4 === fiber.tag; } @@ -4770,25 +5242,29 @@ function commitPlacement(finishedWork) { parent = parent.return; } throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } + parent = parentFiber.stateNode; switch (parentFiber.tag) { case 5: - parent = parentFiber.stateNode; var isContainer = !1; break; case 3: - parent = parentFiber.stateNode.containerInfo; + parent = parent.containerInfo; isContainer = !0; break; case 4: - parent = parentFiber.stateNode.containerInfo; + parent = parent.containerInfo; isContainer = !0; break; default: throw ReactError( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ) ); } parentFiber.effectTag & 16 && (parentFiber.effectTag &= -17); @@ -4818,25 +5294,26 @@ function commitPlacement(finishedWork) { } } for (var node = finishedWork; ; ) { - if (5 === node.tag || 6 === node.tag) { - var stateNode = node.stateNode; + var isHost = 5 === node.tag || 6 === node.tag; + if (isHost || 20 === node.tag) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; if (parentFiber) if (isContainer) { if ("number" === typeof parent) throw ReactError( - "Container does not support insertBefore operation" + Error("Container does not support insertBefore operation") ); } else { - var parentInstance = parent, - beforeChild = parentFiber, - children = parentInstance._children, + isHost = parent; + var beforeChild = parentFiber, + children = isHost._children, index = children.indexOf(stateNode); 0 <= index ? (children.splice(index, 1), (beforeChild = children.indexOf(beforeChild)), children.splice(beforeChild, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [index], [beforeChild], [], @@ -4846,7 +5323,7 @@ function commitPlacement(finishedWork) { : ((index = children.indexOf(beforeChild)), children.splice(index, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [], [], [ @@ -4863,16 +5340,16 @@ function commitPlacement(finishedWork) { ? ReactNativePrivateInterface.UIManager.setChildren(parent, [ "number" === typeof stateNode ? stateNode : stateNode._nativeTag ]) - : ((parentInstance = parent), + : ((isHost = parent), (children = "number" === typeof stateNode ? stateNode : stateNode._nativeTag), - (index = parentInstance._children), + (index = isHost._children), (beforeChild = index.indexOf(stateNode)), 0 <= beforeChild ? (index.splice(beforeChild, 1), index.push(stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [beforeChild], [index.length - 1], [], @@ -4881,7 +5358,7 @@ function commitPlacement(finishedWork) { )) : (index.push(stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [], [], [children], @@ -4916,19 +5393,21 @@ function unmountHostComponents(current$$1) { a: for (;;) { if (null === currentParentIsValid) throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); + currentParent = currentParentIsValid.stateNode; switch (currentParentIsValid.tag) { case 5: - currentParent = currentParentIsValid.stateNode; currentParentIsContainer = !1; break a; case 3: - currentParent = currentParentIsValid.stateNode.containerInfo; + currentParent = currentParent.containerInfo; currentParentIsContainer = !0; break a; case 4: - currentParent = currentParentIsValid.stateNode.containerInfo; + currentParent = currentParent.containerInfo; currentParentIsContainer = !0; break a; } @@ -4936,52 +5415,37 @@ function unmountHostComponents(current$$1) { } currentParentIsValid = !0; } - if (5 === node.tag || 6 === node.tag) { - a: for (var root = node, node$jscomp$0 = root; ; ) - if ( - (commitUnmount(node$jscomp$0), - null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) - ) - (node$jscomp$0.child.return = node$jscomp$0), - (node$jscomp$0 = node$jscomp$0.child); - else { - if (node$jscomp$0 === root) break; - for (; null === node$jscomp$0.sibling; ) { - if (null === node$jscomp$0.return || node$jscomp$0.return === root) - break a; - node$jscomp$0 = node$jscomp$0.return; - } - node$jscomp$0.sibling.return = node$jscomp$0.return; - node$jscomp$0 = node$jscomp$0.sibling; - } - if (currentParentIsContainer) - (root = currentParent), - recursivelyUncacheFiberNode(node.stateNode), - ReactNativePrivateInterface.UIManager.manageChildren( - root, - [], - [], - [], - [], - [0] - ); - else { - root = currentParent; - var child = node.stateNode; - recursivelyUncacheFiberNode(child); - node$jscomp$0 = root._children; - child = node$jscomp$0.indexOf(child); - node$jscomp$0.splice(child, 1); + if (5 === node.tag || 6 === node.tag) + if ((commitNestedUnmounts(node), currentParentIsContainer)) { + var parentInstance = currentParent; + recursivelyUncacheFiberNode(node.stateNode); ReactNativePrivateInterface.UIManager.manageChildren( - root._nativeTag, + parentInstance, [], [], [], [], - [child] + [0] ); - } - } else if (4 === node.tag) { + } else removeChild(currentParent, node.stateNode); + else if (20 === node.tag) + if ( + ((parentInstance = node.stateNode.instance), + commitNestedUnmounts(node), + currentParentIsContainer) + ) { + var parentInstance$jscomp$0 = currentParent; + recursivelyUncacheFiberNode(parentInstance); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance$jscomp$0, + [], + [], + [], + [], + [0] + ); + } else removeChild(currentParent, parentInstance); + else if (4 === node.tag) { if (null !== node.child) { currentParent = node.stateNode.containerInfo; currentParentIsContainer = !0; @@ -5023,7 +5487,7 @@ function commitWork(current$$1, finishedWork) { finishedWork.updateQueue = null; null !== updatePayload && ((finishedWork = instance.viewConfig), - (instanceProps[instance._nativeTag] = newProps), + instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, current$$1, @@ -5041,7 +5505,9 @@ function commitWork(current$$1, finishedWork) { case 6: if (null === finishedWork.stateNode) throw ReactError( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ) ); ReactNativePrivateInterface.UIManager.updateView( finishedWork.stateNode, @@ -5049,44 +5515,99 @@ function commitWork(current$$1, finishedWork) { { text: finishedWork.memoizedProps } ); break; - case 20: - break; case 3: break; case 12: break; case 13: - commitSuspenseComponent(finishedWork); + instance = finishedWork; + null === finishedWork.memoizedState + ? (newProps = !1) + : ((newProps = !0), + (instance = finishedWork.child), + (globalMostRecentFallbackTime = now())); + if (null !== instance) + a: for (current$$1 = instance; ; ) { + if (5 === current$$1.tag) + if (((updatePayload = current$$1.stateNode), newProps)) { + var viewConfig = updatePayload.viewConfig; + var updatePayload$jscomp$0 = diffProperties( + null, + emptyObject, + { style: { display: "none" } }, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } else { + updatePayload = current$$1.stateNode; + updatePayload$jscomp$0 = current$$1.memoizedProps; + viewConfig = updatePayload.viewConfig; + var prevProps = Object.assign({}, updatePayload$jscomp$0, { + style: [updatePayload$jscomp$0.style, { display: "none" }] + }); + updatePayload$jscomp$0 = diffProperties( + null, + prevProps, + updatePayload$jscomp$0, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } + else { + if (6 === current$$1.tag) throw Error("Not yet implemented."); + if (13 === current$$1.tag && null !== current$$1.memoizedState) { + updatePayload = current$$1.child.sibling; + updatePayload.return = current$$1; + current$$1 = updatePayload; + continue; + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + } + if (current$$1 === instance) break a; + for (; null === current$$1.sibling; ) { + if (null === current$$1.return || current$$1.return === instance) + break a; + current$$1 = current$$1.return; + } + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + attachSuspenseRetryListeners(finishedWork); + break; + case 19: + attachSuspenseRetryListeners(finishedWork); break; case 17: break; - case 19: + case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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 commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState, - newDidTimeout = void 0, - primaryChildParent = finishedWork; - null === newState - ? (newDidTimeout = !1) - : ((newDidTimeout = !0), - (primaryChildParent = finishedWork.child), - 0 === newState.fallbackExpirationTime && - (newState.fallbackExpirationTime = requestCurrentTime() - 500)); - null !== primaryChildParent && - hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); - newState = finishedWork.updateQueue; - if (null !== newState) { +function attachSuspenseRetryListeners(finishedWork) { + var thenables = finishedWork.updateQueue; + if (null !== thenables) { finishedWork.updateQueue = null; var retryCache = finishedWork.stateNode; null === retryCache && (retryCache = finishedWork.stateNode = new PossiblyWeakSet$1()); - newState.forEach(function(thenable) { + thenables.forEach(function(thenable) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); retryCache.has(thenable) || ((retry = tracing.unstable_wrap(retry)), @@ -5097,7 +5618,7 @@ function commitSuspenseComponent(finishedWork) { } var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; expirationTime.payload = { element: null }; var error = errorInfo.value; @@ -5108,7 +5629,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { @@ -5134,64 +5655,29 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { }); return expirationTime; } -function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null; - case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -2049) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: - return ( - (effectTag = workInProgress.effectTag), - effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null - ); - case 18: - return null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 19: - case 20: - return null; - default: - return null; - } -} var ceil = Math.ceil, ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - LegacyUnbatchedPhase = 2, - RenderPhase = 4, - CommitPhase = 5, + NoContext = 0, + LegacyUnbatchedContext = 8, + RenderContext = 16, + CommitContext = 32, RootIncomplete = 0, RootErrored = 1, RootSuspended = 2, - RootCompleted = 3, - workPhase = 0, + RootSuspendedWithDelay = 3, + RootCompleted = 4, + executionContext = NoContext, workInProgressRoot = null, workInProgress = null, renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, - workInProgressRootMostRecentEventTime = 1073741823, + workInProgressRootLatestProcessedExpirationTime = 1073741823, + workInProgressRootLatestSuspenseTimeout = 1073741823, + workInProgressRootCanSuspendUsingConfig = null, + workInProgressRootHasPendingPing = !1, + globalMostRecentFallbackTime = 0, + FALLBACK_THROTTLE_MS = 500, nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, @@ -5202,36 +5688,52 @@ var ceil = Math.ceil, rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, + spawnedWorkDuringRender = null, currentEventTime = 0; function requestCurrentTime() { - return workPhase === RenderPhase || workPhase === CommitPhase - ? 1073741822 - ((now() / 10) | 0) + return (executionContext & (RenderContext | CommitContext)) !== NoContext + ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime ? currentEventTime - : (currentEventTime = 1073741822 - ((now() / 10) | 0)); -} -function computeExpirationForFiber(currentTime, fiber) { - if (0 === (fiber.mode & 1)) return 1073741823; - if (workPhase === RenderPhase) return renderExpirationTime; - switch (getCurrentPriorityLevel()) { - case 99: - currentTime = 1073741823; - break; - case 98: - currentTime = - 1073741822 - 10 * ((((1073741822 - currentTime + 15) / 10) | 0) + 1); - break; - case 97: - case 96: - currentTime = - 1073741822 - 25 * ((((1073741822 - currentTime + 500) / 25) | 0) + 1); - break; - case 95: - currentTime = 1; - break; - default: - throw ReactError("Expected a valid priority level"); - } + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); +} +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + fiber = fiber.mode; + if (0 === (fiber & 2)) return 1073741823; + var priorityLevel = getCurrentPriorityLevel(); + if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; + if ((executionContext & RenderContext) !== NoContext) + return renderExpirationTime; + if (null !== suspenseConfig) + currentTime = + 1073741821 - + 25 * + ((((1073741821 - + currentTime + + (suspenseConfig.timeoutMs | 0 || 5e3) / 10) / + 25) | + 0) + + 1); + else + switch (priorityLevel) { + case 99: + currentTime = 1073741823; + break; + case 98: + currentTime = + 1073741821 - 10 * ((((1073741821 - currentTime + 15) / 10) | 0) + 1); + break; + case 97: + case 96: + currentTime = + 1073741821 - 25 * ((((1073741821 - currentTime + 500) / 25) | 0) + 1); + break; + case 95: + currentTime = 1; + break; + default: + throw ReactError(Error("Expected a valid priority level")); + } null !== workInProgressRoot && currentTime === renderExpirationTime && --currentTime; @@ -5242,33 +5744,42 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) )); fiber = markUpdateTimeFromFiberToRoot(fiber, expirationTime); - if (null !== fiber) - if (((fiber.pingTime = 0), 1073741823 === expirationTime)) - if (workPhase === LegacyUnbatchedPhase) + if (null !== fiber) { + fiber.pingTime = 0; + var priorityLevel = getCurrentPriorityLevel(); + if (1073741823 === expirationTime) + if ( + (executionContext & LegacyUnbatchedContext) !== NoContext && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + scheduleInteractions( + fiber, + expirationTime, + tracing.__interactionsRef.current + ); for ( - expirationTime = renderRoot(fiber, 1073741823, !0); - null !== expirationTime; + var callback = renderRoot(fiber, 1073741823, !0); + null !== callback; ) - expirationTime = expirationTime(!0); - else + callback = callback(!0); + } else scheduleCallbackForRoot(fiber, 99, 1073741823), - 0 === workPhase && flushImmediateQueue(); - else { - var priorityLevel = getCurrentPriorityLevel(); - if (98 === priorityLevel) - if (null === rootsWithPendingDiscreteUpdates) - rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]]); - else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(fiber); - (void 0 === lastDiscreteTime || lastDiscreteTime > expirationTime) && - rootsWithPendingDiscreteUpdates.set(fiber, expirationTime); - } - scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); - } + executionContext === NoContext && flushSyncCallbackQueue(); + else scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); + (executionContext & 4) === NoContext || + (98 !== priorityLevel && 99 !== priorityLevel) || + (null === rootsWithPendingDiscreteUpdates + ? (rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]])) + : ((priorityLevel = rootsWithPendingDiscreteUpdates.get(fiber)), + (void 0 === priorityLevel || priorityLevel > expirationTime) && + rootsWithPendingDiscreteUpdates.set(fiber, expirationTime))); + } } function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { fiber.expirationTime < expirationTime && @@ -5309,23 +5820,30 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode); root.callbackExpirationTime = expirationTime; - existingCallbackNode = null; - 1073741823 !== expirationTime && - 1 !== expirationTime && - ((existingCallbackNode = 10 * (1073741822 - expirationTime) - now()), - 5e3 < existingCallbackNode && (existingCallbackNode = 5e3), - (existingCallbackNode = { timeout: existingCallbackNode })); - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - existingCallbackNode - ); + 1073741823 === expirationTime + ? (root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + )) + : ((existingCallbackNode = null), + 1 !== expirationTime && + (existingCallbackNode = { + timeout: 10 * (1073741821 - expirationTime) - now() + }), + (root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + existingCallbackNode + ))); } - schedulePendingInteraction(root, expirationTime); + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); } function runRootCallback(root, callback, isSync) { var prevCallbackNode = root.callbackNode, @@ -5348,9 +5866,7 @@ function resolveLocksOnRoot(root, expirationTime) { return null !== firstBatch && firstBatch._defer && firstBatch._expirationTime >= expirationTime - ? ((root.finishedWork = root.current.alternate), - (root.pendingCommitExpirationTime = expirationTime), - scheduleCallback(97, function() { + ? (scheduleCallback(97, function() { firstBatch._onComplete(); return null; }), @@ -5362,13 +5878,14 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback(99, renderRoot.bind(null, root, expirationTime)); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = 0; + root.finishedWork = null; + root.finishedExpirationTime = 0; var timeoutHandle = root.timeoutHandle; -1 !== timeoutHandle && ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); @@ -5392,6 +5909,12 @@ function prepareFreshStack(root, expirationTime) { case 4: popHostContainer(interruptedWork); break; + case 13: + pop(suspenseStackCursor, interruptedWork); + break; + case 19: + pop(suspenseStackCursor, interruptedWork); + break; case 10: popProvider(interruptedWork); } @@ -5401,27 +5924,35 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = 1073741823; + workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = !1; + spawnedWorkDuringRender = null; } function renderRoot(root$jscomp$0, expirationTime, isSync) { - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); if (root$jscomp$0.firstPendingTime < expirationTime) return null; - if (root$jscomp$0.pendingCommitExpirationTime === expirationTime) - return ( - (root$jscomp$0.pendingCommitExpirationTime = 0), - commitRoot.bind(null, root$jscomp$0, expirationTime) - ); + if (isSync && root$jscomp$0.finishedExpirationTime === expirationTime) + return commitRoot.bind(null, root$jscomp$0); flushPassiveEffects(); if ( root$jscomp$0 !== workInProgressRoot || expirationTime !== renderExpirationTime ) prepareFreshStack(root$jscomp$0, expirationTime), - startWorkOnPendingInteraction(root$jscomp$0, expirationTime); + startWorkOnPendingInteractions(root$jscomp$0, expirationTime); + else if (workInProgressRootExitStatus === RootSuspendedWithDelay) + if (workInProgressRootHasPendingPing) + prepareFreshStack(root$jscomp$0, expirationTime); + else { + var lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + } if (null !== workInProgress) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + lastPendingTime = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; null === prevDispatcher && (prevDispatcher = ContextOnlyDispatcher); ReactCurrentDispatcher.current = ContextOnlyDispatcher; @@ -5432,8 +5963,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) return ( - (workPhase = prevWorkPhase), - resetContextDependences(), + (executionContext = lastPendingTime), + resetContextDependencies(), (ReactCurrentDispatcher.current = prevDispatcher), (tracing.__interactionsRef.current = prevInteractions), renderRoot.bind(null, root$jscomp$0, currentTime) @@ -5450,14 +5981,14 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = performUnitOfWork(workInProgress); break; } catch (thrownValue) { - resetContextDependences(); + resetContextDependencies(); resetHooks(); currentTime = workInProgress; if (null === currentTime || null === currentTime.return) throw (prepareFreshStack(root$jscomp$0, expirationTime), - (workPhase = prevWorkPhase), + (executionContext = lastPendingTime), thrownValue); - currentTime.mode & 4 && + currentTime.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(currentTime, !0); a: { var root = root$jscomp$0, @@ -5472,29 +6003,41 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; + var thenable = value, + hasInvisibleParentBoundary = + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext); value = returnFiber; do { - if ( - 13 === value.tag && - (void 0 === value.memoizedProps.fallback - ? 0 - : null === value.memoizedState) - ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === value.tag)) + null !== value.memoizedState + ? (JSCompiler_temp = !1) + : ((JSCompiler_temp = value.memoizedProps), + (JSCompiler_temp = + void 0 === JSCompiler_temp.fallback + ? !1 + : !0 !== JSCompiler_temp.unstable_avoidThisFallback + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0)); + if (JSCompiler_temp) { returnFiber = value.updateQueue; null === returnFiber ? ((returnFiber = new Set()), returnFiber.add(thenable), (value.updateQueue = returnFiber)) : returnFiber.add(thenable); - if (0 === (value.mode & 1)) { + if (0 === (value.mode & 2)) { value.effectTag |= 64; sourceFiber.effectTag &= -1957; 1 === sourceFiber.tag && (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((renderExpirationTime$jscomp$0 = createUpdate( - 1073741823 + 1073741823, + null )), (renderExpirationTime$jscomp$0.tag = 2), enqueueUpdate( @@ -5506,15 +6049,15 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { } sourceFiber = root; root = renderExpirationTime$jscomp$0; - var pingCache = sourceFiber.pingCache; - null === pingCache - ? ((pingCache = sourceFiber.pingCache = new PossiblyWeakMap()), + hasInvisibleParentBoundary = sourceFiber.pingCache; + null === hasInvisibleParentBoundary + ? ((hasInvisibleParentBoundary = sourceFiber.pingCache = new PossiblyWeakMap()), (returnFiber = new Set()), - pingCache.set(thenable, returnFiber)) - : ((returnFiber = pingCache.get(thenable)), + hasInvisibleParentBoundary.set(thenable, returnFiber)) + : ((returnFiber = hasInvisibleParentBoundary.get(thenable)), void 0 === returnFiber && ((returnFiber = new Set()), - pingCache.set(thenable, returnFiber))); + hasInvisibleParentBoundary.set(thenable, returnFiber))); returnFiber.has(root) || (returnFiber.add(root), (sourceFiber = pingSuspendedRoot.bind( @@ -5537,11 +6080,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { getStackByFiberInDevAndProd(sourceFiber) ); } - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootErrored; + workInProgressRootExitStatus !== RootCompleted && + (workInProgressRootExitStatus = RootErrored); value = createCapturedValue(value, sourceFiber); sourceFiber = returnFiber; do { @@ -5593,80 +6133,148 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = completeUnitOfWork(currentTime); } while (1); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = lastPendingTime; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; tracing.__interactionsRef.current = prevInteractions; if (null !== workInProgress) return renderRoot.bind(null, root$jscomp$0, expirationTime); } + root$jscomp$0.finishedWork = root$jscomp$0.current.alternate; + root$jscomp$0.finishedExpirationTime = expirationTime; if (resolveLocksOnRoot(root$jscomp$0, expirationTime)) return null; workInProgressRoot = null; switch (workInProgressRootExitStatus) { case RootIncomplete: - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); case RootErrored: return ( - (prevWorkPhase = root$jscomp$0.lastPendingTime), - root$jscomp$0.lastPendingTime < expirationTime - ? renderRoot.bind(null, root$jscomp$0, prevWorkPhase) + (lastPendingTime = root$jscomp$0.lastPendingTime), + lastPendingTime < expirationTime + ? renderRoot.bind(null, root$jscomp$0, lastPendingTime) : isSync - ? commitRoot.bind(null, root$jscomp$0, expirationTime) + ? commitRoot.bind(null, root$jscomp$0) : (prepareFreshStack(root$jscomp$0, expirationTime), - scheduleCallback( - 99, + scheduleSyncCallback( renderRoot.bind(null, root$jscomp$0, expirationTime) ), null) ); case RootSuspended: + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + !isSync && + ((isSync = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < isSync) + ) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); + lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + isSync + ); + return null; + } + return commitRoot.bind(null, root$jscomp$0); + case RootSuspendedWithDelay: if (!isSync) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); isSync = root$jscomp$0.lastPendingTime; - if (root$jscomp$0.lastPendingTime < expirationTime) + if (isSync < expirationTime) return renderRoot.bind(null, root$jscomp$0, isSync); - if ( - 1073741823 !== workInProgressRootMostRecentEventTime && - ((prevWorkPhase = - 10 * (1073741822 - workInProgressRootMostRecentEventTime) - 5e3), - (isSync = now()), - (prevWorkPhase = isSync - prevWorkPhase), - (prevWorkPhase = - (120 > prevWorkPhase - ? 120 - : 480 > prevWorkPhase - ? 480 - : 1080 > prevWorkPhase - ? 1080 - : 1920 > prevWorkPhase - ? 1920 - : 3e3 > prevWorkPhase - ? 3e3 - : 4320 > prevWorkPhase - ? 4320 - : 1960 * ceil(prevWorkPhase / 1960)) - prevWorkPhase), - (isSync = 10 * (1073741822 - expirationTime) - isSync), - isSync < prevWorkPhase && (prevWorkPhase = isSync), - (isSync = prevWorkPhase), - 10 < isSync) - ) + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (isSync = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (isSync = 0) + : ((isSync = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (lastPendingTime = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - lastPendingTime), + (isSync = lastPendingTime - isSync), + 0 > isSync && (isSync = 0), + (isSync = + (120 > isSync + ? 120 + : 480 > isSync + ? 480 + : 1080 > isSync + ? 1080 + : 1920 > isSync + ? 1920 + : 3e3 > isSync + ? 3e3 + : 4320 > isSync + ? 4320 + : 1960 * ceil(isSync / 1960)) - isSync), + expirationTime < isSync && (isSync = expirationTime)); + if (10 < isSync) return ( (root$jscomp$0.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root$jscomp$0, expirationTime), + commitRoot.bind(null, root$jscomp$0), isSync )), null ); } - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return commitRoot.bind(null, root$jscomp$0); case RootCompleted: - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return !isSync && + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig && + ((lastPendingTime = workInProgressRootLatestProcessedExpirationTime), + (prevDispatcher = workInProgressRootCanSuspendUsingConfig), + (expirationTime = prevDispatcher.busyMinDurationMs | 0), + 0 >= expirationTime + ? (expirationTime = 0) + : ((isSync = prevDispatcher.busyDelayMs | 0), + (lastPendingTime = + now() - + (10 * (1073741821 - lastPendingTime) - + (prevDispatcher.timeoutMs | 0 || 5e3))), + (expirationTime = + lastPendingTime <= isSync + ? 0 + : isSync + expirationTime - lastPendingTime)), + 10 < expirationTime) + ? ((root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + expirationTime + )), + null) + : commitRoot.bind(null, root$jscomp$0); default: - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } } +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 1 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 1 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} function performUnitOfWork(unitOfWork) { var current$$1 = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 4) + 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), @@ -5683,7 +6291,7 @@ function completeUnitOfWork(unitOfWork) { var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 1024)) { - if (0 === (workInProgress.mode & 4)) + if (0 === (workInProgress.mode & 8)) current$$1 = completeWork( current$$1, workInProgress, @@ -5703,7 +6311,7 @@ function completeUnitOfWork(unitOfWork) { fiber = workInProgress; if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; - if (0 !== (fiber.mode & 4)) { + if (0 !== (fiber.mode & 8)) { for ( var actualDuration = fiber.actualDuration, treeBaseDuration = fiber.selfBaseDuration, @@ -5755,7 +6363,7 @@ function completeUnitOfWork(unitOfWork) { (unitOfWork.lastEffect = workInProgress))); } else { current$$1 = unwindWork(workInProgress, renderExpirationTime); - if (0 !== (workInProgress.mode & 4)) { + if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; for ( @@ -5781,8 +6389,8 @@ function completeUnitOfWork(unitOfWork) { (workInProgressRootExitStatus = RootCompleted); return null; } -function commitRoot(root, expirationTime) { - runWithPriority(99, commitRootImpl.bind(null, root, expirationTime)); +function commitRoot(root) { + runWithPriority(99, commitRootImpl.bind(null, root)); null !== rootWithPendingPassiveEffects && ((root = getCurrentPriorityLevel()), scheduleCallback(root, function() { @@ -5791,13 +6399,21 @@ function commitRoot(root, expirationTime) { })); return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); - var finishedWork = root.current.alternate; - if (null === finishedWork) - throw ReactError("Should have a work-in-progress root."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); + var finishedWork = root.finishedWork, + expirationTime = root.finishedExpirationTime; + if (null === finishedWork) return null; + root.finishedWork = null; + root.finishedExpirationTime = 0; + if (finishedWork === root.current) + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); root.callbackNode = null; root.callbackExpirationTime = 0; var updateExpirationTimeBeforeCommit = finishedWork.expirationTime, @@ -5811,19 +6427,19 @@ function commitRootImpl(root, expirationTime) { (root.lastPendingTime = updateExpirationTimeBeforeCommit); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); - if (1 < finishedWork.effectTag) - if (null !== finishedWork.lastEffect) { - finishedWork.lastEffect.nextEffect = finishedWork; - var firstEffect = finishedWork.firstEffect; - } else firstEffect = finishedWork; - else firstEffect = finishedWork.firstEffect; - if (null !== firstEffect) { - updateExpirationTimeBeforeCommit = workPhase; - workPhase = CommitPhase; - childExpirationTimeBeforeCommit = tracing.__interactionsRef.current; + 1 < finishedWork.effectTag + ? null !== finishedWork.lastEffect + ? ((finishedWork.lastEffect.nextEffect = finishedWork), + (updateExpirationTimeBeforeCommit = finishedWork.firstEffect)) + : (updateExpirationTimeBeforeCommit = finishedWork) + : (updateExpirationTimeBeforeCommit = finishedWork.firstEffect); + if (null !== updateExpirationTimeBeforeCommit) { + childExpirationTimeBeforeCommit = executionContext; + executionContext |= CommitContext; + var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; ReactCurrentOwner$2.current = null; - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5866,11 +6482,12 @@ function commitRootImpl(root, expirationTime) { case 6: case 4: case 17: - case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5878,13 +6495,13 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); commitTime = now$1(); - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5919,24 +6536,26 @@ function commitRootImpl(root, expirationTime) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; null !== alternate && ((alternate.return = null), (alternate.child = null), (alternate.memoizedState = null), - (alternate.updateQueue = null)); + (alternate.updateQueue = null), + (alternate.dependencies = null)); } nextEffect = nextEffect.nextEffect; } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); root.current = finishedWork; - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for ( @@ -6012,26 +6631,27 @@ function commitRootImpl(root, expirationTime) { break; case 12: var onRender = currentRef.memoizedProps.onRender; - onRender( - currentRef.memoizedProps.id, - null === current$$1$jscomp$1 ? "mount" : "update", - currentRef.actualDuration, - currentRef.treeBaseDuration, - currentRef.actualStartTime, - commitTime, - current$$1.memoizedInteractions - ); + "function" === typeof onRender && + onRender( + currentRef.memoizedProps.id, + null === current$$1$jscomp$1 ? "mount" : "update", + currentRef.actualDuration, + currentRef.treeBaseDuration, + currentRef.actualStartTime, + commitTime, + current$$1.memoizedInteractions + ); break; case 13: + case 19: case 17: - break; case 20: break; - case 19: - break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -6056,32 +6676,51 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); nextEffect = null; - tracing.__interactionsRef.current = childExpirationTimeBeforeCommit; - workPhase = updateExpirationTimeBeforeCommit; + requestPaint(); + tracing.__interactionsRef.current = prevInteractions; + executionContext = childExpirationTimeBeforeCommit; } else (root.current = finishedWork), (commitTime = now$1()); - rootDoesHavePassiveEffects - ? ((rootDoesHavePassiveEffects = !1), + if ((effectTag$jscomp$0 = rootDoesHavePassiveEffects)) + (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsExpirationTime = expirationTime)) - : finishPendingInteractions(root, expirationTime); - expirationTime = root.firstPendingTime; - 0 !== expirationTime - ? ((effectTag$jscomp$0 = requestCurrentTime()), - (effectTag$jscomp$0 = inferPriorityFromExpirationTime( - effectTag$jscomp$0, - expirationTime - )), - scheduleCallbackForRoot(root, effectTag$jscomp$0, expirationTime)) - : (legacyErrorBoundariesThatAlreadyFailed = null); + (pendingPassiveEffectsExpirationTime = expirationTime); + else + for (nextEffect = updateExpirationTimeBeforeCommit; null !== nextEffect; ) + (current$$1$jscomp$1 = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + (nextEffect = current$$1$jscomp$1); + current$$1$jscomp$1 = root.firstPendingTime; + if (0 !== current$$1$jscomp$1) { + instance$jscomp$0 = requestCurrentTime(); + instance$jscomp$0 = inferPriorityFromExpirationTime( + instance$jscomp$0, + current$$1$jscomp$1 + ); + if (null !== spawnedWorkDuringRender) + for ( + prevProps$jscomp$0 = spawnedWorkDuringRender, + spawnedWorkDuringRender = null, + updateQueue = 0; + updateQueue < prevProps$jscomp$0.length; + updateQueue++ + ) + scheduleInteractions( + root, + prevProps$jscomp$0[updateQueue], + root.memoizedInteractions + ); + scheduleCallbackForRoot(root, instance$jscomp$0, current$$1$jscomp$1); + } else legacyErrorBoundariesThatAlreadyFailed = null; + effectTag$jscomp$0 || finishPendingInteractions(root, expirationTime); "function" === typeof onCommitFiberRoot && - onCommitFiberRoot(finishedWork.stateNode); - 1073741823 === expirationTime + onCommitFiberRoot(finishedWork.stateNode, expirationTime); + 1073741823 === current$$1$jscomp$1 ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -6091,8 +6730,8 @@ function commitRootImpl(root, expirationTime) { (root = firstUncaughtError), (firstUncaughtError = null), root); - if (workPhase === LegacyUnbatchedPhase) return null; - flushImmediateQueue(); + if ((executionContext & LegacyUnbatchedContext) !== NoContext) return null; + flushSyncCallbackQueue(); return null; } function flushPassiveEffects() { @@ -6103,25 +6742,36 @@ function flushPassiveEffects() { pendingPassiveEffectsExpirationTime = 0; var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Cannot flush passive effects while already rendering."); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; for (var effect = root.current.firstEffect; null !== effect; ) { try { var finishedWork = effect; - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if (0 !== (finishedWork.effectTag & 512)) + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork), + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + } } catch (error) { - if (null === effect) throw ReactError("Should be working on an effect."); + if (null === effect) + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(effect, error); } - effect = effect.nextEffect; + finishedWork = effect.nextEffect; + effect.nextEffect = null; + effect = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); return !0; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -6162,11 +6812,18 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); workInProgressRoot === root && renderExpirationTime === suspendedTime - ? prepareFreshStack(root, renderExpirationTime) + ? workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ? prepareFreshStack(root, renderExpirationTime) + : (workInProgressRootHasPendingPing = !0) : root.lastPendingTime < suspendedTime || ((thenable = root.pingTime), (0 !== thenable && thenable < suspendedTime) || ((root.pingTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), (thenable = requestCurrentTime()), (thenable = inferPriorityFromExpirationTime(thenable, suspendedTime)), scheduleCallbackForRoot(root, thenable, suspendedTime))); @@ -6175,7 +6832,7 @@ function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(thenable); retryCache = requestCurrentTime(); - thenable = computeExpirationForFiber(retryCache, boundaryFiber); + thenable = computeExpirationForFiber(retryCache, boundaryFiber, null); retryCache = inferPriorityFromExpirationTime(retryCache, thenable); boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && @@ -6228,6 +6885,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, renderExpirationTime ); + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( current$$1, workInProgress, @@ -6235,6 +6897,39 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); return null !== workInProgress ? workInProgress.sibling : null; } + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); + break; + case 19: + updateExpirationTime = 0 !== (current$$1.effectTag & 64); + if (workInProgress.childExpirationTime < renderExpirationTime) + return ( + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ), + updateExpirationTime && (workInProgress.effectTag |= 64), + null + ); + if (updateExpirationTime) + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + updateExpirationTime = workInProgress.memoizedState; + null !== updateExpirationTime && + ((updateExpirationTime.rendering = null), + (updateExpirationTime.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); } return bailoutOnAlreadyFinishedWork( current$$1, @@ -6370,9 +7065,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { break; default: throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." + Error( + "Element type is invalid. Received a promise that resolves to: " + + context + + ". Lazy element type must resolve to a class or function." + ) ); } return workInProgress; @@ -6413,7 +7110,9 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime = workInProgress.updateQueue; if (null === updateExpirationTime) throw ReactError( - "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." + 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." + ) ); context = workInProgress.memoizedState; context = null !== context ? context.element : null; @@ -6569,16 +7268,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== oldValue; ) { - var list = oldValue.contextDependencies; + var list = oldValue.dependencies; if (null !== list) { getDerivedStateFromProps = oldValue.child; - for (var dependency = list.first; null !== dependency; ) { + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { if ( dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { 1 === oldValue.tag && - ((dependency = createUpdate(renderExpirationTime)), + ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), enqueueUpdate(oldValue, dependency)); oldValue.expirationTime < renderExpirationTime && @@ -6587,22 +7290,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); - dependency = renderExpirationTime; - for (var node = oldValue.return; null !== node; ) { - var alternate = node.alternate; - if (node.childExpirationTime < dependency) - (node.childExpirationTime = dependency), - null !== alternate && - alternate.childExpirationTime < dependency && - (alternate.childExpirationTime = dependency); - else if ( - null !== alternate && - alternate.childExpirationTime < dependency - ) - alternate.childExpirationTime = dependency; - else break; - node = node.return; - } + scheduleWorkOnParentPath( + oldValue.return, + renderExpirationTime + ); list.expirationTime < renderExpirationTime && (list.expirationTime = renderExpirationTime); break; @@ -6729,13 +7420,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ) ); + case 19: + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); }; -function schedulePendingInteraction(root, expirationTime) { - var interactions = tracing.__interactionsRef.current; +function scheduleInteractions(root, expirationTime, interactions) { if (0 < interactions.size) { var pendingInteractionMap = root.pendingInteractionMap, pendingInteractions = pendingInteractionMap.get(expirationTime); @@ -6756,7 +7454,7 @@ function schedulePendingInteraction(root, expirationTime) { ); } } -function startWorkOnPendingInteraction(root, expirationTime) { +function startWorkOnPendingInteractions(root, expirationTime) { var interactions = new Set(); root.pendingInteractionMap.forEach(function( scheduledInteractions, @@ -6820,6 +7518,34 @@ function finishPendingInteractions(root, committedExpirationTime) { }); } } +var onCommitFiberRoot = null, + onCommitFiberUnmount = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled || !hook.supportsFiber) return !0; + try { + var rendererID = hook.inject(internals); + onCommitFiberRoot = function(root, expirationTime) { + try { + var didError = 64 === (root.current.effectTag & 64), + currentTime = requestCurrentTime(), + priorityLevel = inferPriorityFromExpirationTime( + currentTime, + expirationTime + ); + hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); + } catch (err) {} + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) {} + }; + } catch (err) {} + return !0; +} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -6827,7 +7553,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.index = 0; this.ref = null; this.pendingProps = pendingProps; - this.contextDependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; + this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; this.effectTag = 0; this.lastEffect = this.firstEffect = this.nextEffect = null; @@ -6881,7 +7607,16 @@ function createWorkInProgress(current, pendingProps) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + pendingProps = current.dependencies; + workInProgress.dependencies = + null === pendingProps + ? null + : { + expirationTime: pendingProps.expirationTime, + firstContext: pendingProps.firstContext, + listeners: pendingProps.listeners, + responders: pendingProps.responders + }; workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; @@ -6911,12 +7646,16 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 3, expirationTime, key); + fiberTag = 8; + mode |= 7; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 2, expirationTime, key); + fiberTag = 8; + mode |= 1; + break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -6925,8 +7664,15 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.elementType = REACT_SUSPENSE_TYPE), (type.type = REACT_SUSPENSE_TYPE), + (type.elementType = REACT_SUSPENSE_TYPE), + (type.expirationTime = expirationTime), + type + ); + case REACT_SUSPENSE_LIST_TYPE: + return ( + (type = createFiber(19, pendingProps, key, mode)), + (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type ); @@ -6951,9 +7697,11 @@ function createFiberFromTypeAndProps( break a; } throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (null == type ? type : typeof type) + - "." + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (null == type ? type : typeof type) + + "." + ) ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -6967,14 +7715,6 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { elements.expirationTime = expirationTime; return elements; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - pendingProps = createFiber(8, pendingProps, key, mode); - mode = 0 === (mode & 1) ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; - pendingProps.elementType = mode; - pendingProps.type = mode; - pendingProps.expirationTime = expirationTime; - return pendingProps; -} function createFiberFromText(content, mode, expirationTime) { content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; @@ -6995,11 +7735,12 @@ function createFiberFromPortal(portal, mode, expirationTime) { }; return mode; } -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pingCache = this.pendingChildren = null; - this.pendingCommitExpirationTime = 0; + this.finishedExpirationTime = 0; this.finishedWork = null; this.timeoutHandle = -1; this.pendingContext = this.context = null; @@ -7014,10 +7755,12 @@ function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { if ("function" === typeof component.render) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } component = findCurrentHostFiber(fiber); @@ -7025,8 +7768,13 @@ function findHostInstance(component) { } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current, - currentTime = requestCurrentTime(); - current$$1 = computeExpirationForFiber(currentTime, current$$1); + currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + current$$1 = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); currentTime = container.current; a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; @@ -7036,7 +7784,9 @@ function updateContainer(element, container, parentComponent, callback) { 1 !== parentComponent.tag ) throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + 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 parentContext = parentComponent; do { @@ -7055,7 +7805,9 @@ function updateContainer(element, container, parentComponent, callback) { parentContext = parentContext.return; } while (null !== parentContext); throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (1 === parentComponent.tag) { @@ -7075,12 +7827,11 @@ function updateContainer(element, container, parentComponent, callback) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(current$$1); - callback.payload = { element: element }; + suspenseConfig = createUpdate(current$$1, suspenseConfig); + suspenseConfig.payload = { element: element }; container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - flushPassiveEffects(); - enqueueUpdate(currentTime, callback); + null !== container && (suspenseConfig.callback = container); + enqueueUpdate(currentTime, suspenseConfig); scheduleUpdateOnFiber(currentTime, current$$1); return current$$1; } @@ -7117,7 +7868,7 @@ function _inherits(subClass, superClass) { var getInspectorDataForViewTag = void 0; getInspectorDataForViewTag = function() { throw ReactError( - "getInspectorDataForViewTag() is not available in production" + Error("getInspectorDataForViewTag() is not available in production") ); }; function findNodeHandle(componentOrHandle) { @@ -7133,19 +7884,19 @@ function findNodeHandle(componentOrHandle) { ? componentOrHandle.canonical._nativeTag : componentOrHandle._nativeTag; } -_batchedUpdatesImpl = function(fn, a) { - if (0 !== workPhase) return fn(a); - workPhase = 1; +batchedUpdatesImpl = function(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= 1; try { return fn(a); } finally { - (workPhase = 0), flushImmediateQueue(); + (executionContext = prevExecutionContext), + executionContext === NoContext && flushSyncCallbackQueue(); } }; -_flushInteractiveUpdatesImpl = function() { - workPhase !== RenderPhase && - workPhase !== CommitPhase && - flushPendingDiscreteUpdates(); +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); }; var roots = new Map(), ReactNativeRenderer = { @@ -7259,6 +8010,14 @@ var roots = new Map(), })(React.Component); })(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + }, setNativeProps: function(handle, nativeProps) { null != handle._nativeTag && ((nativeProps = diffProperties( @@ -7277,9 +8036,9 @@ var roots = new Map(), render: function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = new FiberRootNode(containerTag, !1); + root = new FiberRootNode(containerTag, 0, !1); var uninitializedFiber = 0; - isDevToolsPresent && (uninitializedFiber |= 4); + isDevToolsPresent && (uninitializedFiber |= 8); uninitializedFiber = createFiber(3, null, null, uninitializedFiber); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -7436,7 +8195,8 @@ var roots = new Map(), findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, - setRefreshHandler: null + setRefreshHandler: null, + getCurrentFiber: null }) ); })({ diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index 2224766b6573fc..e32498979c427b 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -16,10 +16,9 @@ var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/R React = require("react"), Scheduler = require("scheduler"), tracing = require("scheduler/tracing"); -function ReactError(message) { - message = Error(message); - message.name = "Invariant Violation"; - return message; +function ReactError(error) { + error.name = "Invariant Violation"; + return error; } var eventPluginOrder = null, namesToPlugins = {}; @@ -30,16 +29,20 @@ function recomputePluginOrdering() { pluginIndex = eventPluginOrder.indexOf(pluginName); if (!(-1 < pluginIndex)) throw ReactError( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ) ); if (!plugins[pluginIndex]) { if (!pluginModule.extractEvents) throw ReactError( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." + Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ) ); plugins[pluginIndex] = pluginModule; pluginIndex = pluginModule.eventTypes; @@ -50,9 +53,11 @@ function recomputePluginOrdering() { eventName$jscomp$0 = eventName; if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ) ); eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -78,11 +83,13 @@ function recomputePluginOrdering() { : (JSCompiler_inline_result = !1); if (!JSCompiler_inline_result) throw ReactError( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ) ); } } @@ -91,9 +98,11 @@ function recomputePluginOrdering() { function publishRegistrationName(registrationName, pluginModule) { if (registrationNameModules[registrationName]) throw ReactError( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." + Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ) ); registrationNameModules[registrationName] = pluginModule; } @@ -142,7 +151,9 @@ function invokeGuardedCallbackAndCatchFirstError( caughtError = null; } else throw ReactError( - "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + Error( + "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." + ) ); hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } @@ -160,7 +171,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; if (Array.isArray(dispatchListener)) - throw ReactError("executeDirectDispatch(...): Invalid `event`."); + throw ReactError(Error("executeDirectDispatch(...): Invalid `event`.")); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null; @@ -173,7 +184,9 @@ function executeDirectDispatch(event) { function accumulateInto(current, next) { if (null == next) throw ReactError( - "accumulateInto(...): Accumulated items must not be null or undefined." + Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ) ); if (null == current) return next; if (Array.isArray(current)) { @@ -210,7 +223,9 @@ var injection = { injectEventPluginOrder: function(injectedEventPluginOrder) { if (eventPluginOrder) throw ReactError( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ) ); eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); @@ -227,9 +242,11 @@ var injection = { ) { if (namesToPlugins[pluginName]) throw ReactError( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." + Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ) ); namesToPlugins[pluginName] = pluginModule; isOrderingDirty = !0; @@ -271,11 +288,13 @@ function getListener(inst, registrationName) { if (inst) return null; if (listener && "function" !== typeof listener) throw ReactError( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." + Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ) ); return listener; } @@ -439,7 +458,9 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { if (!(event instanceof this)) throw ReactError( - "Trying to release an event instance into a pool of a different type." + Error( + "Trying to release an event instance into a pool of a different type." + ) ); event.destructor(); 10 > this.eventPool.length && this.eventPool.push(event); @@ -475,7 +496,8 @@ function timestampForTouch(touch) { } function getTouchIdentifier(_ref) { _ref = _ref.identifier; - if (null == _ref) throw ReactError("Touch object is missing identifier."); + if (null == _ref) + throw ReactError(Error("Touch object is missing identifier.")); return _ref; } function recordTouchStart(touch) { @@ -518,7 +540,7 @@ function recordTouchMove(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch move without a touch start.\nTouch Move: %s\n", "Touch Bank: %s", printTouch(touch), @@ -536,7 +558,7 @@ function recordTouchEnd(touch) { (touchRecord.currentPageY = touch.pageY), (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) - : console.error( + : console.warn( "Cannot record touch end without a touch start.\nTouch End: %s\n", "Touch Bank: %s", printTouch(touch), @@ -590,7 +612,7 @@ var ResponderTouchHistoryStore = { function accumulate(current, next) { if (null == next) throw ReactError( - "accumulate(...): Accumulated items must not be null or undefined." + Error("accumulate(...): Accumulated items must not be null or undefined.") ); return null == current ? next @@ -968,7 +990,9 @@ injection.injectEventPluginsByName({ directDispatchConfig = customDirectEventTypes[topLevelType]; if (!bubbleDispatchConfig && !directDispatchConfig) throw ReactError( - 'Unsupported top level event type "' + topLevelType + '" dispatched' + Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ) ); topLevelType = SyntheticEvent.getPooled( bubbleDispatchConfig || directDispatchConfig, @@ -985,33 +1009,38 @@ injection.injectEventPluginsByName({ } } }); -var instanceCache = {}, - instanceProps = {}; +var instanceCache = new Map(), + instanceProps = new Map(); function getInstanceFromTag(tag) { - return instanceCache[tag] || null; + return instanceCache.get(tag) || null; } var restoreTarget = null, restoreQueue = null; function restoreStateOfTarget(target) { if (getInstanceFromNode(target)) throw ReactError( - "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ) ); } -function _batchedUpdatesImpl(fn, bookkeeping) { +function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } -function _flushInteractiveUpdatesImpl() {} -var isBatching = !1; +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { - if (isBatching) return fn(bookkeeping); - isBatching = !0; + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - if (((isBatching = !1), null !== restoreTarget || null !== restoreQueue)) + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) if ( - (_flushInteractiveUpdatesImpl(), + (flushDiscreteUpdatesImpl(), restoreTarget && ((bookkeeping = restoreTarget), (fn = restoreQueue), @@ -1048,7 +1077,9 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { forEachAccumulated(events, executeDispatchesAndReleaseTopLevel); if (eventQueue) throw ReactError( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ) ); if (hasRethrowError) throw ((events = rethrowError), @@ -1096,13 +1127,13 @@ ReactNativePrivateInterface.RCTEventEmitter.register({ } }); getFiberCurrentPropsFromNode = function(stateNode) { - return instanceProps[stateNode._nativeTag] || null; + return instanceProps.get(stateNode._nativeTag) || null; }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { var tag = inst.stateNode._nativeTag; void 0 === tag && (tag = inst.stateNode.canonical._nativeTag); - if (!tag) throw ReactError("All native instances should have a tag."); + if (!tag) throw ReactError(Error("All native instances should have a tag.")); return tag; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1119,6 +1150,8 @@ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher") || (ReactSharedInternals.ReactCurrentDispatcher = { current: null }); +ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig") || + (ReactSharedInternals.ReactCurrentBatchConfig = { suspense: null }); var hasSymbol = "function" === typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, @@ -1132,11 +1165,13 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, + REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; -hasSymbol && Symbol.for("react.event_component"); -hasSymbol && Symbol.for("react.event_target"); -hasSymbol && Symbol.for("react.event_target.touch_hit"); +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; @@ -1150,8 +1185,6 @@ function getComponentName(type) { if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return "ConcurrentMode"; case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PORTAL_TYPE: @@ -1162,6 +1195,8 @@ function getComponentName(type) { return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1196,14 +1231,14 @@ function isFiberMountedImpl(fiber) { } function assertIsMounted(fiber) { if (2 !== isFiberMountedImpl(fiber)) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; if (!alternate) { alternate = isFiberMountedImpl(fiber); if (3 === alternate) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return 1 === alternate ? null : fiber; } for (var a = fiber, b = alternate; ; ) { @@ -1224,7 +1259,7 @@ function findCurrentFiberUsingSlowPath(fiber) { if (parentB === b) return assertIsMounted(parentA), alternate; parentB = parentB.sibling; } - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); } if (a.return !== b.return) (a = parentA), (b = parentB); else { @@ -1261,17 +1296,21 @@ function findCurrentFiberUsingSlowPath(fiber) { } if (!didFindChild) throw ReactError( - "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + Error( + "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." + ) ); } } if (a.alternate !== b) throw ReactError( - "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + Error( + "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (3 !== a.tag) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); return a.stateNode.current === a ? fiber : alternate; } function findCurrentHostFiber(parent) { @@ -1586,7 +1625,9 @@ var ReactNativeFiberHostComponent = (function() { })(); function shim$1() { throw ReactError( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ) ); } var getViewConfigForType = @@ -1601,11 +1642,11 @@ function allocateTag() { } function recursivelyUncacheFiberNode(node) { if ("number" === typeof node) - delete instanceCache[node], delete instanceProps[node]; + instanceCache.delete(node), instanceProps.delete(node); else { var tag = node._nativeTag; - delete instanceCache[tag]; - delete instanceProps[tag]; + instanceCache.delete(tag); + instanceProps.delete(tag); node._children.forEach(recursivelyUncacheFiberNode); } } @@ -1621,8 +1662,22 @@ function finalizeInitialChildren(parentInstance) { return !1; } var scheduleTimeout = setTimeout, - cancelTimeout = clearTimeout, - BEFORE_SLASH_RE = /^(.*)[\\\/]/; + cancelTimeout = clearTimeout; +function removeChild(parentInstance, child) { + recursivelyUncacheFiberNode(child); + var children = parentInstance._children; + child = children.indexOf(child); + children.splice(child, 1); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, + [], + [], + [], + [], + [child] + ); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; function getStackByFiberInDevAndProd(workInProgress) { var info = ""; do { @@ -1708,7 +1763,9 @@ function popTopLevelContextObject(fiber) { function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw ReactError( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ) ); push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); @@ -1721,10 +1778,12 @@ function processChildContext(fiber, type, parentContext) { for (var contextKey in instance) if (!(contextKey in fiber)) throw ReactError( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ) ); return Object.assign({}, parentContext, instance); } @@ -1746,7 +1805,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { var instance = workInProgress.stateNode; if (!instance) throw ReactError( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ) ); didChange ? ((type = processChildContext(workInProgress, type, previousContext)), @@ -1757,40 +1818,11 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } -var onCommitFiberRoot = null, - onCommitFiberUnmount = null; -function catchErrors(fn) { - return function(arg) { - try { - return fn(arg); - } catch (err) {} - }; -} -var isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; -function injectInternals(internals) { - if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - if (hook.isDisabled || !hook.supportsFiber) return !0; - try { - var rendererID = hook.inject(internals); - onCommitFiberRoot = catchErrors(function(root) { - hook.onCommitFiberRoot( - rendererID, - root, - void 0, - 64 === (root.current.effectTag & 64) - ); - }); - onCommitFiberUnmount = catchErrors(function(fiber) { - return hook.onCommitFiberUnmount(rendererID, fiber); - }); - } catch (err) {} - return !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 = Scheduler.unstable_now, Scheduler_getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel, @@ -1804,12 +1836,16 @@ if ( null == tracing.__interactionsRef.current ) throw ReactError( - "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 http://fb.me/react-profiling" + 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 http://fb.me/react-profiling" + ) ); var fakeCallbackNode = {}, - immediateQueue = null, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, immediateQueueCallbackNode = null, - isFlushingImmediate = !1, + isFlushingSyncQueue = !1, initialTimeMs = Scheduler_now(), now = 1e4 > initialTimeMs @@ -1830,7 +1866,7 @@ function getCurrentPriorityLevel() { case Scheduler_IdlePriority: return 95; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function reactPriorityToSchedulerPriority(reactPriorityLevel) { @@ -1846,7 +1882,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case 95: return Scheduler_IdlePriority; default: - throw ReactError("Unknown priority level."); + throw ReactError(Error("Unknown priority level.")); } } function runWithPriority(reactPriorityLevel, fn) { @@ -1854,46 +1890,47 @@ function runWithPriority(reactPriorityLevel, fn) { return Scheduler_runWithPriority(reactPriorityLevel, fn); } function scheduleCallback(reactPriorityLevel, callback, options) { - if (99 === reactPriorityLevel) - return ( - null === immediateQueue - ? ((immediateQueue = [callback]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushImmediateQueueImpl - ))) - : immediateQueue.push(callback), - fakeCallbackNode - ); reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function flushImmediateQueue() { +function scheduleSyncCallback(callback) { + null === syncQueue + ? ((syncQueue = [callback]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(callback); + return fakeCallbackNode; +} +function flushSyncCallbackQueue() { null !== immediateQueueCallbackNode && Scheduler_cancelCallback(immediateQueueCallbackNode); - flushImmediateQueueImpl(); + flushSyncCallbackQueueImpl(); } -function flushImmediateQueueImpl() { - if (!isFlushingImmediate && null !== immediateQueue) { - isFlushingImmediate = !0; +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; var i = 0; try { - for (; i < immediateQueue.length; i++) { - var callback = immediateQueue[i]; - do callback = callback(!0); - while (null !== callback); - } - immediateQueue = null; + 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 !== immediateQueue && - (immediateQueue = immediateQueue.slice(i + 1)), + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), Scheduler_scheduleCallback( Scheduler_ImmediatePriority, - flushImmediateQueue + flushSyncCallbackQueue ), error); } finally { - isFlushingImmediate = !1; + isFlushingSyncQueue = !1; } } } @@ -1901,7 +1938,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (1073741823 === expirationTime) return 99; if (1 === expirationTime) return 95; currentTime = - 10 * (1073741822 - expirationTime) - 10 * (1073741822 - currentTime); + 10 * (1073741821 - expirationTime) - 10 * (1073741821 - currentTime); return 0 >= currentTime ? 99 : 250 >= currentTime @@ -1983,7 +2020,7 @@ var valueCursor = { current: null }, currentlyRenderingFiber = null, lastContextDependency = null, lastContextWithAllBitsObserved = null; -function resetContextDependences() { +function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } function pushProvider(providerFiber, nextValue) { @@ -1996,14 +2033,32 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); providerFiber.type._context._currentValue = currentValue; } +function scheduleWorkOnParentPath(parent, renderExpirationTime) { + for (; null !== parent; ) { + var alternate = parent.alternate; + if (parent.childExpirationTime < renderExpirationTime) + (parent.childExpirationTime = renderExpirationTime), + null !== alternate && + alternate.childExpirationTime < renderExpirationTime && + (alternate.childExpirationTime = renderExpirationTime); + else if ( + null !== alternate && + alternate.childExpirationTime < renderExpirationTime + ) + alternate.childExpirationTime = renderExpirationTime; + else break; + parent = parent.return; + } +} function prepareToReadContext(workInProgress, renderExpirationTime) { currentlyRenderingFiber = workInProgress; lastContextWithAllBitsObserved = lastContextDependency = null; - var currentDependencies = workInProgress.contextDependencies; - null !== currentDependencies && - currentDependencies.expirationTime >= renderExpirationTime && - (didReceiveUpdate = !0); - workInProgress.contextDependencies = null; + workInProgress = workInProgress.dependencies; + null !== workInProgress && + null !== workInProgress.firstContext && + (workInProgress.expirationTime >= renderExpirationTime && + (didReceiveUpdate = !0), + (workInProgress.firstContext = null)); } function readContext(context, observedBits) { if ( @@ -2017,12 +2072,16 @@ function readContext(context, observedBits) { if (null === lastContextDependency) { if (null === currentlyRenderingFiber) throw ReactError( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ) ); lastContextDependency = observedBits; - currentlyRenderingFiber.contextDependencies = { - first: observedBits, - expirationTime: 0 + currentlyRenderingFiber.dependencies = { + expirationTime: 0, + firstContext: observedBits, + listeners: null, + responders: null }; } else lastContextDependency = lastContextDependency.next = observedBits; } @@ -2055,9 +2114,10 @@ function cloneUpdateQueue(currentQueue) { lastCapturedEffect: null }; } -function createUpdate(expirationTime) { +function createUpdate(expirationTime, suspenseConfig) { return { expirationTime: expirationTime, + suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, @@ -2173,8 +2233,10 @@ function processUpdateQueue( ((newFirstUpdate = update), (newBaseState = resultState)), newExpirationTime < updateExpirationTime && (newExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), (resultState = getStateFromUpdate( workInProgress, queue, @@ -2250,15 +2312,18 @@ function commitUpdateEffects(effect, instance) { var context = instance; if ("function" !== typeof _callback3) throw ReactError( - "Invalid argument passed as callback. Expected a function. Instead received: " + - _callback3 + Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + _callback3 + ) ); _callback3.call(context); } effect = effect.nextEffect; } } -var emptyRefsObject = new React.Component().refs; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, + emptyRefsObject = new React.Component().refs; function applyDerivedStateFromProps( workInProgress, ctor, @@ -2285,36 +2350,42 @@ var classComponentUpdater = { }, enqueueSetState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 1; + suspenseConfig.payload = payload; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, inst); - var update = createUpdate(currentTime); - update.tag = 2; - void 0 !== callback && null !== callback && (update.callback = callback); - flushPassiveEffects(); - enqueueUpdate(inst, update); + var currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, inst, suspenseConfig); + suspenseConfig = createUpdate(currentTime, suspenseConfig); + suspenseConfig.tag = 2; + void 0 !== callback && + null !== callback && + (suspenseConfig.callback = callback); + enqueueUpdate(inst, suspenseConfig); scheduleUpdateOnFiber(inst, currentTime); } }; @@ -2443,15 +2514,19 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw ReactError( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + Error( + "Function components cannot have refs. Did you mean to use React.forwardRef()?" + ) ); inst = element.stateNode; } if (!inst) throw ReactError( - "Missing owner for string ref " + - returnFiber + - ". This error is likely caused by a bug in React. Please file an issue." + Error( + "Missing owner for string ref " + + returnFiber + + ". This error is likely caused by a bug in React. Please file an issue." + ) ); var stringRef = "" + returnFiber; if ( @@ -2471,13 +2546,17 @@ function coerceRef(returnFiber, current$$1, element) { } if ("string" !== typeof returnFiber) throw ReactError( - "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + Error( + "Expected ref to be a function, a string, an object returned by React.createRef(), or null." + ) ); if (!element._owner) throw ReactError( - "Element ref was specified as a string (" + - returnFiber + - ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + Error( + "Element ref was specified as a string (" + + returnFiber + + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." + ) ); } return returnFiber; @@ -2485,11 +2564,13 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) throw ReactError( - "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + - ")." + Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === Object.prototype.toString.call(newChild) + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : newChild) + + ")." + ) ); } function ChildReconciler(shouldTrackSideEffects) { @@ -2892,11 +2973,13 @@ function ChildReconciler(shouldTrackSideEffects) { var iteratorFn = getIteratorFn(newChildrenIterable); if ("function" !== typeof iteratorFn) throw ReactError( - "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + Error( + "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." + ) ); newChildrenIterable = iteratorFn.call(newChildrenIterable); if (null == newChildrenIterable) - throw ReactError("An iterable object provided no iterator."); + throw ReactError(Error("An iterable object provided no iterator.")); for ( var previousNewFiber = (iteratorFn = null), oldFiber = currentFirstChild, @@ -3131,8 +3214,10 @@ function ChildReconciler(shouldTrackSideEffects) { case 0: throw ((returnFiber = returnFiber.type), ReactError( - (returnFiber.displayName || returnFiber.name || "Component") + - "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + Error( + (returnFiber.displayName || returnFiber.name || "Component") + + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." + ) )); } return deleteRemainingChildren(returnFiber, currentFirstChild); @@ -3147,7 +3232,9 @@ var reconcileChildFibers = ChildReconciler(!0), function requiredContext(c) { if (c === NO_CONTEXT) throw ReactError( - "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." + ) ); return c; } @@ -3185,6 +3272,50 @@ function popHostContext(fiber) { contextFiberStackCursor.current === fiber && (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } +var SubtreeSuspenseContextMask = 1, + InvisibleParentSuspenseContext = 1, + ForceSuspenseFallback = 2, + suspenseStackCursor = { current: 0 }; +function findFirstSuspended(row) { + for (var node = row; null !== node; ) { + if (13 === node.tag) { + if (null !== node.memoizedState) return node; + } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { + if (0 !== (node.effectTag & 64)) return node; + } else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; +} +var currentListenerHookIndex = 0; +function updateListenerHook(responder, props) { + var dependencies = null.dependencies; + null === dependencies && + (dependencies = null.dependencies = { + expirationTime: 0, + firstContext: null, + listeners: [], + responders: null + }); + var listeners = dependencies.listeners; + null === listeners && (dependencies.listeners = listeners = []); + listeners.length === currentListenerHookIndex + ? (listeners.push({ responder: responder, props: props }), + currentListenerHookIndex++) + : ((listeners = listeners[currentListenerHookIndex++]), + (listeners.responder = responder), + (listeners.props = props)); +} var NoEffect$1 = 0, UnmountSnapshot = 2, UnmountMutation = 4, @@ -3209,7 +3340,9 @@ var NoEffect$1 = 0, numberOfReRenders = 0; function throwInvalidHookError() { throw ReactError( - "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + Error( + "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." + ) ); } function areHookInputsEqual(nextDeps, prevDeps) { @@ -3259,7 +3392,9 @@ function renderWithHooks( sideEffectTag = 0; if (current) throw ReactError( - "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + Error( + "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." + ) ); return workInProgress; } @@ -3295,7 +3430,9 @@ function updateWorkInProgressHook() { (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) - throw ReactError("Rendered more hooks than during the previous render."); + throw ReactError( + Error("Rendered more hooks than during the previous render.") + ); currentHook = nextCurrentHook; var newHook = { memoizedState: currentHook.memoizedState, @@ -3320,7 +3457,9 @@ function updateReducer(reducer) { queue = hook.queue; if (null === queue) throw ReactError( - "Should have a queue. This is likely a bug in React. Please file an issue." + Error( + "Should have a queue. This is likely a bug in React. Please file an issue." + ) ); queue.lastRenderedReducer = reducer; if (0 < numberOfReRenders) { @@ -3363,8 +3502,10 @@ function updateReducer(reducer) { (firstRenderPhaseUpdate = newState)), updateExpirationTime > remainingExpirationTime && (remainingExpirationTime = updateExpirationTime)) - : (updateExpirationTime < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = updateExpirationTime), + : (markRenderEventTimeAndConfig( + updateExpirationTime, + _update.suspenseConfig + ), (newState = _update.eagerReducer === reducer ? _update.eagerState @@ -3443,7 +3584,9 @@ function mountDebugValue() {} function dispatchAction(fiber, queue, action) { if (!(25 > numberOfReRenders)) throw ReactError( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." + Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ) ); var alternate = fiber.alternate; if ( @@ -3454,6 +3597,7 @@ function dispatchAction(fiber, queue, action) { ((didScheduleRenderPhaseUpdate = !0), (fiber = { expirationTime: renderExpirationTime$1, + suspenseConfig: null, action: action, eagerReducer: null, eagerState: null, @@ -3469,24 +3613,29 @@ function dispatchAction(fiber, queue, action) { queue.next = fiber; } else { - flushPassiveEffects(); - var currentTime = requestCurrentTime(); - currentTime = computeExpirationForFiber(currentTime, fiber); - var _update2 = { - expirationTime: currentTime, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }, - _last = queue.last; - if (null === _last) _update2.next = _update2; + var currentTime = requestCurrentTime(), + _suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber( + currentTime, + fiber, + _suspenseConfig + ); + _suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: _suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var _last = queue.last; + if (null === _last) _suspenseConfig.next = _suspenseConfig; else { var first = _last.next; - null !== first && (_update2.next = first); - _last.next = _update2; + null !== first && (_suspenseConfig.next = first); + _last.next = _suspenseConfig; } - queue.last = _update2; + queue.last = _suspenseConfig; if ( 0 === fiber.expirationTime && (null === alternate || 0 === alternate.expirationTime) && @@ -3495,8 +3644,8 @@ function dispatchAction(fiber, queue, action) { try { var currentState = queue.lastRenderedState, _eagerState = alternate(currentState, action); - _update2.eagerReducer = alternate; - _update2.eagerState = _eagerState; + _suspenseConfig.eagerReducer = alternate; + _suspenseConfig.eagerState = _eagerState; if (is(_eagerState, currentState)) return; } catch (error) { } finally { @@ -3515,7 +3664,8 @@ var ContextOnlyDispatcher = { useReducer: throwInvalidHookError, useRef: throwInvalidHookError, useState: throwInvalidHookError, - useDebugValue: throwInvalidHookError + useDebugValue: throwInvalidHookError, + useListener: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3588,7 +3738,8 @@ var ContextOnlyDispatcher = { ); return [hook.memoizedState, initialState]; }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, HooksDispatcherOnUpdate = { readContext: readContext, @@ -3642,7 +3793,8 @@ var ContextOnlyDispatcher = { useState: function(initialState) { return updateReducer(basicStateReducer, initialState); }, - useDebugValue: mountDebugValue + useDebugValue: mountDebugValue, + useListener: updateListenerHook }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -4198,6 +4350,7 @@ function pushHostRootContext(workInProgress) { pushTopLevelContextObject(workInProgress, root.context, !1); pushHostContainer(workInProgress, root.containerInfo); } +var SUSPENDED_MARKER = {}; function updateSuspenseComponent( current$$1, workInProgress, @@ -4205,35 +4358,50 @@ function updateSuspenseComponent( ) { var mode = workInProgress.mode, nextProps = workInProgress.pendingProps, - nextState = workInProgress.memoizedState; - if (0 === (workInProgress.effectTag & 64)) { - nextState = null; - var nextDidTimeout = !1; - } else - (nextState = { - fallbackExpirationTime: - null !== nextState ? nextState.fallbackExpirationTime : 0 - }), + suspenseContext = suspenseStackCursor.current, + nextState = null, + nextDidTimeout = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || + (JSCompiler_temp = + 0 !== (suspenseContext & ForceSuspenseFallback) && + (null === current$$1 || null !== current$$1.memoizedState)); + JSCompiler_temp + ? ((nextState = SUSPENDED_MARKER), (nextDidTimeout = !0), - (workInProgress.effectTag &= -65); + (workInProgress.effectTag &= -65)) + : (null !== current$$1 && null === current$$1.memoizedState) || + void 0 === nextProps.fallback || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= InvisibleParentSuspenseContext); + suspenseContext &= SubtreeSuspenseContextMask; + push(suspenseStackCursor, suspenseContext, workInProgress); if (null === current$$1) if (nextDidTimeout) { - var nextFallbackChildren = nextProps.fallback; + nextProps = nextProps.fallback; current$$1 = createFiberFromFragment(null, mode, 0, null); - 0 === (workInProgress.mode & 1) && - (current$$1.child = - null !== workInProgress.memoizedState - ? workInProgress.child.child - : workInProgress.child); + current$$1.return = workInProgress; + if (0 === (workInProgress.mode & 2)) + for ( + nextDidTimeout = + null !== workInProgress.memoizedState + ? workInProgress.child.child + : workInProgress.child, + current$$1.child = nextDidTimeout; + null !== nextDidTimeout; + + ) + (nextDidTimeout.return = current$$1), + (nextDidTimeout = nextDidTimeout.sibling); renderExpirationTime = createFiberFromFragment( - nextFallbackChildren, + nextProps, mode, renderExpirationTime, null ); + renderExpirationTime.return = workInProgress; current$$1.sibling = renderExpirationTime; mode = current$$1; - mode.return = renderExpirationTime.return = workInProgress; } else mode = renderExpirationTime = mountChildFibers( workInProgress, @@ -4244,95 +4412,235 @@ function updateSuspenseComponent( else { if (null !== current$$1.memoizedState) if ( - ((nextFallbackChildren = current$$1.child), - (mode = nextFallbackChildren.sibling), + ((suspenseContext = current$$1.child), + (mode = suspenseContext.sibling), nextDidTimeout) ) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - nextFallbackChildren, - nextFallbackChildren.pendingProps, + suspenseContext, + suspenseContext.pendingProps, 0 ); - 0 === (workInProgress.mode & 1) && + renderExpirationTime.return = workInProgress; + if ( + 0 === (workInProgress.mode & 2) && ((nextDidTimeout = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== nextFallbackChildren.child && - (renderExpirationTime.child = nextDidTimeout)); - if (workInProgress.mode & 4) { - nextFallbackChildren = 0; + nextDidTimeout !== suspenseContext.child) + ) for ( - nextDidTimeout = renderExpirationTime.child; + renderExpirationTime.child = nextDidTimeout; null !== nextDidTimeout; ) - (nextFallbackChildren += nextDidTimeout.treeBaseDuration), + (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - renderExpirationTime.treeBaseDuration = nextFallbackChildren; + if (workInProgress.mode & 8) { + nextDidTimeout = 0; + for ( + suspenseContext = renderExpirationTime.child; + null !== suspenseContext; + + ) + (nextDidTimeout += suspenseContext.treeBaseDuration), + (suspenseContext = suspenseContext.sibling); + renderExpirationTime.treeBaseDuration = nextDidTimeout; } - nextFallbackChildren = renderExpirationTime.sibling = createWorkInProgress( - mode, - nextProps, - mode.expirationTime - ); + nextProps = createWorkInProgress(mode, nextProps, mode.expirationTime); + nextProps.return = workInProgress; + renderExpirationTime.sibling = nextProps; mode = renderExpirationTime; renderExpirationTime.childExpirationTime = 0; - renderExpirationTime = nextFallbackChildren; - mode.return = renderExpirationTime.return = workInProgress; + renderExpirationTime = nextProps; } else mode = renderExpirationTime = reconcileChildFibers( workInProgress, - nextFallbackChildren.child, + suspenseContext.child, nextProps.children, renderExpirationTime ); - else { - var _currentPrimaryChild = current$$1.child; - if (nextDidTimeout) { - nextProps = nextProps.fallback; - nextFallbackChildren = createFiberFromFragment(null, mode, 0, null); - nextFallbackChildren.child = _currentPrimaryChild; - 0 === (workInProgress.mode & 1) && - (nextFallbackChildren.child = + else if (((suspenseContext = current$$1.child), nextDidTimeout)) { + nextDidTimeout = nextProps.fallback; + nextProps = createFiberFromFragment(null, mode, 0, null); + nextProps.return = workInProgress; + nextProps.child = suspenseContext; + null !== suspenseContext && (suspenseContext.return = nextProps); + if (0 === (workInProgress.mode & 2)) + for ( + suspenseContext = null !== workInProgress.memoizedState ? workInProgress.child.child - : workInProgress.child); - if (workInProgress.mode & 4) { - nextDidTimeout = 0; - for ( - _currentPrimaryChild = nextFallbackChildren.child; - null !== _currentPrimaryChild; + : workInProgress.child, + nextProps.child = suspenseContext; + null !== suspenseContext; + ) + (suspenseContext.return = nextProps), + (suspenseContext = suspenseContext.sibling); + if (workInProgress.mode & 8) { + suspenseContext = 0; + for (JSCompiler_temp = nextProps.child; null !== JSCompiler_temp; ) + (suspenseContext += JSCompiler_temp.treeBaseDuration), + (JSCompiler_temp = JSCompiler_temp.sibling); + nextProps.treeBaseDuration = suspenseContext; + } + renderExpirationTime = createFiberFromFragment( + nextDidTimeout, + mode, + renderExpirationTime, + null + ); + renderExpirationTime.return = workInProgress; + nextProps.sibling = renderExpirationTime; + renderExpirationTime.effectTag |= 2; + mode = nextProps; + nextProps.childExpirationTime = 0; + } else + renderExpirationTime = mode = reconcileChildFibers( + workInProgress, + suspenseContext, + nextProps.children, + renderExpirationTime + ); + workInProgress.stateNode = current$$1.stateNode; + } + workInProgress.memoizedState = nextState; + workInProgress.child = mode; + return renderExpirationTime; +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailExpiration = 0), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren( + current$$1, + workInProgress, + nextProps.children, + renderExpirationTime + ); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & ForceSuspenseFallback)) + (nextProps = + (nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback), + (workInProgress.effectTag |= 64); + else { + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) { + if (null !== current$$1.memoizedState) { + current$$1.expirationTime < renderExpirationTime && + (current$$1.expirationTime = renderExpirationTime); + var alternate = current$$1.alternate; + null !== alternate && + alternate.expirationTime < renderExpirationTime && + (alternate.expirationTime = renderExpirationTime); + scheduleWorkOnParentPath(current$$1.return, renderExpirationTime); + } + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress ) - (nextDidTimeout += _currentPrimaryChild.treeBaseDuration), - (_currentPrimaryChild = _currentPrimaryChild.sibling); - nextFallbackChildren.treeBaseDuration = nextDidTimeout; + break a; + current$$1 = current$$1.return; } - renderExpirationTime = nextFallbackChildren.sibling = createFiberFromFragment( - nextProps, - mode, + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + nextProps &= SubtreeSuspenseContextMask; + } + push(suspenseStackCursor, nextProps, workInProgress); + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderExpirationTime = workInProgress.child; + for (revealOrder = null; null !== renderExpirationTime; ) + (nextProps = renderExpirationTime.alternate), + null !== nextProps && + null === findFirstSuspended(nextProps) && + (revealOrder = renderExpirationTime), + (renderExpirationTime = renderExpirationTime.sibling); + renderExpirationTime = revealOrder; + null === renderExpirationTime + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderExpirationTime.sibling), + (renderExpirationTime.sibling = null)); + initSuspenseListRenderState( + workInProgress, + !1, + revealOrder, renderExpirationTime, - null + tailMode ); - renderExpirationTime.effectTag |= 2; - mode = nextFallbackChildren; - nextFallbackChildren.childExpirationTime = 0; - mode.return = renderExpirationTime.return = workInProgress; - } else - renderExpirationTime = mode = reconcileChildFibers( + break; + case "backwards": + renderExpirationTime = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + nextProps = revealOrder.alternate; + if (null !== nextProps && null === findFirstSuspended(nextProps)) { + workInProgress.child = revealOrder; + break; + } + nextProps = revealOrder.sibling; + revealOrder.sibling = renderExpirationTime; + renderExpirationTime = revealOrder; + revealOrder = nextProps; + } + initSuspenseListRenderState( workInProgress, - _currentPrimaryChild, - nextProps.children, - renderExpirationTime + !0, + renderExpirationTime, + null, + tailMode ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; } - workInProgress.stateNode = current$$1.stateNode; - } - workInProgress.memoizedState = nextState; - workInProgress.child = mode; - return renderExpirationTime; + return workInProgress.child; } function bailoutOnAlreadyFinishedWork( current$$1, @@ -4340,11 +4648,11 @@ function bailoutOnAlreadyFinishedWork( renderExpirationTime ) { null !== current$$1 && - (workInProgress.contextDependencies = current$$1.contextDependencies); + (workInProgress.dependencies = current$$1.dependencies); profilerStartTime = -1; if (workInProgress.childExpirationTime < renderExpirationTime) return null; if (null !== current$$1 && workInProgress.child !== current$$1.child) - throw ReactError("Resuming work not yet implemented."); + throw ReactError(Error("Resuming work not yet implemented.")); if (null !== workInProgress.child) { current$$1 = workInProgress.child; renderExpirationTime = createWorkInProgress( @@ -4376,6 +4684,7 @@ var appendAllChildren = void 0, appendAllChildren = function(parent, workInProgress) { for (var node = workInProgress.child; null !== node; ) { if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); + else if (20 === node.tag) parent._children.push(node.stateNode.instance); else if (4 !== node.tag && null !== node.child) { node.child.return = node; node = node.child; @@ -4400,6 +4709,30 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { updateHostText$1 = function(current, workInProgress, oldText, newText) { oldText !== newText && (workInProgress.effectTag |= 4); }; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var _lastTailNode = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (_lastTailNode = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === _lastTailNode + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (_lastTailNode.sibling = null); + } +} function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4426,22 +4759,24 @@ function completeWork(current, workInProgress, renderExpirationTime) { break; case 5: popHostContext(workInProgress); - renderExpirationTime = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - type, + renderExpirationTime, newProps, - renderExpirationTime + rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); else if (newProps) { current = requiredContext(contextStackCursor$1.current); var tag = allocateTag(), - viewConfig = getViewConfigForType(type), + viewConfig = getViewConfigForType(renderExpirationTime), updatePayload = diffProperties( null, emptyObject, @@ -4451,25 +4786,27 @@ function completeWork(current, workInProgress, renderExpirationTime) { ReactNativePrivateInterface.UIManager.createView( tag, viewConfig.uiViewClassName, - renderExpirationTime, + rootContainerInstance, updatePayload ); viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); - instanceCache[tag] = workInProgress; - instanceProps[tag] = newProps; + instanceCache.set(tag, workInProgress); + instanceProps.set(tag, newProps); appendAllChildren(viewConfig, workInProgress, !1, !1); finalizeInitialChildren( viewConfig, - type, - newProps, renderExpirationTime, + newProps, + rootContainerInstance, current ) && (workInProgress.effectTag |= 4); workInProgress.stateNode = viewConfig; null !== workInProgress.ref && (workInProgress.effectTag |= 128); } else if (null === workInProgress.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); break; case 6: @@ -4483,57 +4820,65 @@ function completeWork(current, workInProgress, renderExpirationTime) { else { if ("string" !== typeof newProps && null === workInProgress.stateNode) throw ReactError( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ) ); current = requiredContext(rootInstanceStackCursor.current); if (!requiredContext(contextStackCursor$1.current).isInAParentText) throw ReactError( - "Text strings must be rendered within a component." + Error("Text strings must be rendered within a component.") ); - renderExpirationTime = allocateTag(); + rootContainerInstance = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - renderExpirationTime, + rootContainerInstance, "RCTRawText", current, { text: newProps } ); - instanceCache[renderExpirationTime] = workInProgress; - workInProgress.stateNode = renderExpirationTime; + instanceCache.set(rootContainerInstance, workInProgress); + workInProgress.stateNode = rootContainerInstance; } break; case 11: break; case 13: + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( (workInProgress.expirationTime = renderExpirationTime), workInProgress ); newProps = null !== newProps; - renderExpirationTime = !1; + rootContainerInstance = !1; null !== current && - ((type = current.memoizedState), - (renderExpirationTime = null !== type), + ((renderExpirationTime = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime), newProps || - null === type || - ((type = type.fallbackExpirationTime), - type < workInProgressRootMostRecentEventTime && - (workInProgressRootMostRecentEventTime = type), - (current = current.child.sibling), - null !== current && - ((type = workInProgress.firstEffect), - null !== type - ? ((workInProgress.firstEffect = current), - (current.nextEffect = type)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = current), - (current.nextEffect = null)), - (current.effectTag = 8)))); - newProps && - !renderExpirationTime && - 0 !== (workInProgress.mode & 1) && - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - if (newProps || renderExpirationTime) workInProgress.effectTag |= 4; + null === renderExpirationTime || + ((renderExpirationTime = current.child.sibling), + null !== renderExpirationTime && + ((tag = workInProgress.firstEffect), + null !== tag + ? ((workInProgress.firstEffect = renderExpirationTime), + (renderExpirationTime.nextEffect = tag)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), + (renderExpirationTime.nextEffect = null)), + (renderExpirationTime.effectTag = 8)))); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & InvisibleParentSuspenseContext) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; break; case 7: break; @@ -4558,62 +4903,233 @@ function completeWork(current, workInProgress, renderExpirationTime) { case 18: break; case 19: + pop(suspenseStackCursor, workInProgress); + newProps = workInProgress.memoizedState; + if (null === newProps) break; + rootContainerInstance = 0 !== (workInProgress.effectTag & 64); + tag = newProps.rendering; + if (null === tag) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = workInProgress.child; null !== current; ) { + tag = findFirstSuspended(current); + if (null !== tag) { + workInProgress.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = tag.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + workInProgress.firstEffect = workInProgress.lastEffect = null; + current = renderExpirationTime; + for (newProps = workInProgress.child; null !== newProps; ) + (rootContainerInstance = newProps), + (tag = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (renderExpirationTime = rootContainerInstance.alternate), + null === renderExpirationTime + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = tag), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null), + (rootContainerInstance.selfBaseDuration = 0), + (rootContainerInstance.treeBaseDuration = 0)) + : ((rootContainerInstance.childExpirationTime = + renderExpirationTime.childExpirationTime), + (rootContainerInstance.expirationTime = + renderExpirationTime.expirationTime), + (rootContainerInstance.child = + renderExpirationTime.child), + (rootContainerInstance.memoizedProps = + renderExpirationTime.memoizedProps), + (rootContainerInstance.memoizedState = + renderExpirationTime.memoizedState), + (rootContainerInstance.updateQueue = + renderExpirationTime.updateQueue), + (tag = renderExpirationTime.dependencies), + (rootContainerInstance.dependencies = + null === tag + ? null + : { + expirationTime: tag.expirationTime, + firstContext: tag.firstContext, + listeners: tag.listeners, + responders: tag.responders + }), + (rootContainerInstance.selfBaseDuration = + renderExpirationTime.selfBaseDuration), + (rootContainerInstance.treeBaseDuration = + renderExpirationTime.treeBaseDuration)), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & SubtreeSuspenseContextMask) | + ForceSuspenseFallback, + workInProgress + ); + return workInProgress.child; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if (((current = findFirstSuspended(tag)), null !== current)) { + if ( + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && "hidden" === newProps.tailMode) + ) { + current = current.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.effectTag |= 4)); + workInProgress = workInProgress.lastEffect = newProps.lastEffect; + null !== workInProgress && (workInProgress.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime && + ((workInProgress.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (current = renderExpirationTime - 1), + (workInProgress.expirationTime = workInProgress.childExpirationTime = current), + null === spawnedWorkDuringRender + ? (spawnedWorkDuringRender = [current]) + : spawnedWorkDuringRender.push(current)); + newProps.isBackwards + ? ((tag.sibling = workInProgress.child), (workInProgress.child = tag)) + : ((current = newProps.last), + null !== current + ? (current.sibling = tag) + : (workInProgress.child = tag), + (newProps.last = tag)); + } + if (null !== newProps.tail) + return ( + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500), + (current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (current.sibling = null), + (newProps = suspenseStackCursor.current), + (newProps = rootContainerInstance + ? (newProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback + : newProps & SubtreeSuspenseContextMask), + push(suspenseStackCursor, newProps, workInProgress), + current + ); break; case 20: break; default: throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); } return null; } -function createCapturedValue(value, source) { - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} -function logCapturedError(capturedError) { - var componentStack = capturedError.componentStack, - error = capturedError.error; - if (error instanceof Error) { - capturedError = error.message; - var name = error.name; - try { - error.message = - (capturedError ? name + ": " + capturedError : name) + - "\n\nThis error is located at:" + - componentStack; - } catch (e) {} - } else - error = - "string" === typeof error - ? Error(error + "\n\nThis error is located at:" + componentStack) - : Error("Unspecified error at:" + componentStack); - ReactNativePrivateInterface.ExceptionsManager.handleException(error, !1); -} -var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; -function logError(boundary, errorInfo) { - var source = errorInfo.source, - stack = errorInfo.stack; - null === stack && - null !== source && - (stack = getStackByFiberInDevAndProd(source)); - errorInfo = { - componentName: null !== source ? getComponentName(source.type) : null, - componentStack: null !== stack ? stack : "", - error: errorInfo.value, - errorBoundary: null, - errorBoundaryName: null, - errorBoundaryFound: !1, - willRetry: !1 - }; - null !== boundary && - 1 === boundary.tag && - ((errorInfo.errorBoundary = boundary.stateNode), - (errorInfo.errorBoundaryName = getComponentName(boundary.type)), +function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case 1: + isContextProvider(workInProgress.type) && popContext(workInProgress); + var effectTag = workInProgress.effectTag; + return effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null; + case 3: + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw ReactError( + Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ) + ); + workInProgress.effectTag = (effectTag & -2049) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor, workInProgress), + (effectTag = workInProgress.effectTag), + effectTag & 2048 + ? ((workInProgress.effectTag = (effectTag & -2049) | 64), + workInProgress) + : null + ); + case 18: + return null; + case 19: + return pop(suspenseStackCursor, workInProgress), null; + case 4: + return popHostContainer(workInProgress), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} +function createCapturedValue(value, source) { + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw ReactError( + Error("Expected ReactFiberErrorDialog.showErrorDialog to be a function.") + ); +function logCapturedError(capturedError) { + !1 !== + ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ) && console.error(capturedError.error); +} +var PossiblyWeakSet$1 = "function" === typeof WeakSet ? WeakSet : Set; +function logError(boundary, errorInfo) { + var source = errorInfo.source, + stack = errorInfo.stack; + null === stack && + null !== source && + (stack = getStackByFiberInDevAndProd(source)); + errorInfo = { + componentName: null !== source ? getComponentName(source.type) : null, + componentStack: null !== stack ? stack : "", + error: errorInfo.value, + errorBoundary: null, + errorBoundaryName: null, + errorBoundaryFound: !1, + willRetry: !1 + }; + null !== boundary && + 1 === boundary.tag && + ((errorInfo.errorBoundary = boundary.stateNode), + (errorInfo.errorBoundaryName = getComponentName(boundary.type)), (errorInfo.errorBoundaryFound = !0), (errorInfo.willRetry = !0)); try { @@ -4652,64 +5168,6 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } while (effect !== finishedWork); } } -function hideOrUnhideAllChildren(finishedWork, isHidden) { - for (var node = finishedWork; ; ) { - if (5 === node.tag) { - var instance = node.stateNode; - if (isHidden) { - var viewConfig = instance.viewConfig; - var updatePayload = diffProperties( - null, - emptyObject, - { style: { display: "none" } }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } else { - instance = node.stateNode; - updatePayload = node.memoizedProps; - viewConfig = instance.viewConfig; - var prevProps = Object.assign({}, updatePayload, { - style: [updatePayload.style, { display: "none" }] - }); - updatePayload = diffProperties( - null, - prevProps, - updatePayload, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); - } - } else { - if (6 === node.tag) throw Error("Not yet implemented."); - if (13 === node.tag && null !== node.memoizedState) { - instance = node.child.sibling; - instance.return = node; - node = instance; - continue; - } else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - } - if (node === finishedWork) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === finishedWork) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -} function commitUnmount(current$$1$jscomp$0) { "function" === typeof onCommitFiberUnmount && onCommitFiberUnmount(current$$1$jscomp$0); @@ -4757,6 +5215,20 @@ function commitUnmount(current$$1$jscomp$0) { unmountHostComponents(current$$1$jscomp$0); } } +function commitNestedUnmounts(root) { + for (var node = root; ; ) + if ((commitUnmount(node), null !== node.child && 4 !== node.tag)) + (node.child.return = node), (node = node.child); + else { + if (node === root) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === root) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +} function isHostParent(fiber) { return 5 === fiber.tag || 3 === fiber.tag || 4 === fiber.tag; } @@ -4770,25 +5242,29 @@ function commitPlacement(finishedWork) { parent = parent.return; } throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } + parent = parentFiber.stateNode; switch (parentFiber.tag) { case 5: - parent = parentFiber.stateNode; var isContainer = !1; break; case 3: - parent = parentFiber.stateNode.containerInfo; + parent = parent.containerInfo; isContainer = !0; break; case 4: - parent = parentFiber.stateNode.containerInfo; + parent = parent.containerInfo; isContainer = !0; break; default: throw ReactError( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ) ); } parentFiber.effectTag & 16 && (parentFiber.effectTag &= -17); @@ -4818,25 +5294,26 @@ function commitPlacement(finishedWork) { } } for (var node = finishedWork; ; ) { - if (5 === node.tag || 6 === node.tag) { - var stateNode = node.stateNode; + var isHost = 5 === node.tag || 6 === node.tag; + if (isHost || 20 === node.tag) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; if (parentFiber) if (isContainer) { if ("number" === typeof parent) throw ReactError( - "Container does not support insertBefore operation" + Error("Container does not support insertBefore operation") ); } else { - var parentInstance = parent, - beforeChild = parentFiber, - children = parentInstance._children, + isHost = parent; + var beforeChild = parentFiber, + children = isHost._children, index = children.indexOf(stateNode); 0 <= index ? (children.splice(index, 1), (beforeChild = children.indexOf(beforeChild)), children.splice(beforeChild, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [index], [beforeChild], [], @@ -4846,7 +5323,7 @@ function commitPlacement(finishedWork) { : ((index = children.indexOf(beforeChild)), children.splice(index, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [], [], [ @@ -4863,16 +5340,16 @@ function commitPlacement(finishedWork) { ? ReactNativePrivateInterface.UIManager.setChildren(parent, [ "number" === typeof stateNode ? stateNode : stateNode._nativeTag ]) - : ((parentInstance = parent), + : ((isHost = parent), (children = "number" === typeof stateNode ? stateNode : stateNode._nativeTag), - (index = parentInstance._children), + (index = isHost._children), (beforeChild = index.indexOf(stateNode)), 0 <= beforeChild ? (index.splice(beforeChild, 1), index.push(stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [beforeChild], [index.length - 1], [], @@ -4881,7 +5358,7 @@ function commitPlacement(finishedWork) { )) : (index.push(stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, + isHost._nativeTag, [], [], [children], @@ -4916,19 +5393,21 @@ function unmountHostComponents(current$$1) { a: for (;;) { if (null === currentParentIsValid) throw ReactError( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ) ); + currentParent = currentParentIsValid.stateNode; switch (currentParentIsValid.tag) { case 5: - currentParent = currentParentIsValid.stateNode; currentParentIsContainer = !1; break a; case 3: - currentParent = currentParentIsValid.stateNode.containerInfo; + currentParent = currentParent.containerInfo; currentParentIsContainer = !0; break a; case 4: - currentParent = currentParentIsValid.stateNode.containerInfo; + currentParent = currentParent.containerInfo; currentParentIsContainer = !0; break a; } @@ -4936,52 +5415,37 @@ function unmountHostComponents(current$$1) { } currentParentIsValid = !0; } - if (5 === node.tag || 6 === node.tag) { - a: for (var root = node, node$jscomp$0 = root; ; ) - if ( - (commitUnmount(node$jscomp$0), - null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) - ) - (node$jscomp$0.child.return = node$jscomp$0), - (node$jscomp$0 = node$jscomp$0.child); - else { - if (node$jscomp$0 === root) break; - for (; null === node$jscomp$0.sibling; ) { - if (null === node$jscomp$0.return || node$jscomp$0.return === root) - break a; - node$jscomp$0 = node$jscomp$0.return; - } - node$jscomp$0.sibling.return = node$jscomp$0.return; - node$jscomp$0 = node$jscomp$0.sibling; - } - if (currentParentIsContainer) - (root = currentParent), - recursivelyUncacheFiberNode(node.stateNode), - ReactNativePrivateInterface.UIManager.manageChildren( - root, - [], - [], - [], - [], - [0] - ); - else { - root = currentParent; - var child = node.stateNode; - recursivelyUncacheFiberNode(child); - node$jscomp$0 = root._children; - child = node$jscomp$0.indexOf(child); - node$jscomp$0.splice(child, 1); + if (5 === node.tag || 6 === node.tag) + if ((commitNestedUnmounts(node), currentParentIsContainer)) { + var parentInstance = currentParent; + recursivelyUncacheFiberNode(node.stateNode); ReactNativePrivateInterface.UIManager.manageChildren( - root._nativeTag, + parentInstance, [], [], [], [], - [child] + [0] ); - } - } else if (4 === node.tag) { + } else removeChild(currentParent, node.stateNode); + else if (20 === node.tag) + if ( + ((parentInstance = node.stateNode.instance), + commitNestedUnmounts(node), + currentParentIsContainer) + ) { + var parentInstance$jscomp$0 = currentParent; + recursivelyUncacheFiberNode(parentInstance); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance$jscomp$0, + [], + [], + [], + [], + [0] + ); + } else removeChild(currentParent, parentInstance); + else if (4 === node.tag) { if (null !== node.child) { currentParent = node.stateNode.containerInfo; currentParentIsContainer = !0; @@ -5023,7 +5487,7 @@ function commitWork(current$$1, finishedWork) { finishedWork.updateQueue = null; null !== updatePayload && ((finishedWork = instance.viewConfig), - (instanceProps[instance._nativeTag] = newProps), + instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, current$$1, @@ -5041,7 +5505,9 @@ function commitWork(current$$1, finishedWork) { case 6: if (null === finishedWork.stateNode) throw ReactError( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ) ); ReactNativePrivateInterface.UIManager.updateView( finishedWork.stateNode, @@ -5049,44 +5515,99 @@ function commitWork(current$$1, finishedWork) { { text: finishedWork.memoizedProps } ); break; - case 20: - break; case 3: break; case 12: break; case 13: - commitSuspenseComponent(finishedWork); + instance = finishedWork; + null === finishedWork.memoizedState + ? (newProps = !1) + : ((newProps = !0), + (instance = finishedWork.child), + (globalMostRecentFallbackTime = now())); + if (null !== instance) + a: for (current$$1 = instance; ; ) { + if (5 === current$$1.tag) + if (((updatePayload = current$$1.stateNode), newProps)) { + var viewConfig = updatePayload.viewConfig; + var updatePayload$jscomp$0 = diffProperties( + null, + emptyObject, + { style: { display: "none" } }, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } else { + updatePayload = current$$1.stateNode; + updatePayload$jscomp$0 = current$$1.memoizedProps; + viewConfig = updatePayload.viewConfig; + var prevProps = Object.assign({}, updatePayload$jscomp$0, { + style: [updatePayload$jscomp$0.style, { display: "none" }] + }); + updatePayload$jscomp$0 = diffProperties( + null, + prevProps, + updatePayload$jscomp$0, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + updatePayload._nativeTag, + viewConfig.uiViewClassName, + updatePayload$jscomp$0 + ); + } + else { + if (6 === current$$1.tag) throw Error("Not yet implemented."); + if (13 === current$$1.tag && null !== current$$1.memoizedState) { + updatePayload = current$$1.child.sibling; + updatePayload.return = current$$1; + current$$1 = updatePayload; + continue; + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; + continue; + } + } + if (current$$1 === instance) break a; + for (; null === current$$1.sibling; ) { + if (null === current$$1.return || current$$1.return === instance) + break a; + current$$1 = current$$1.return; + } + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; + } + attachSuspenseRetryListeners(finishedWork); + break; + case 19: + attachSuspenseRetryListeners(finishedWork); break; case 17: break; - case 19: + case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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 commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState, - newDidTimeout = void 0, - primaryChildParent = finishedWork; - null === newState - ? (newDidTimeout = !1) - : ((newDidTimeout = !0), - (primaryChildParent = finishedWork.child), - 0 === newState.fallbackExpirationTime && - (newState.fallbackExpirationTime = requestCurrentTime() - 500)); - null !== primaryChildParent && - hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); - newState = finishedWork.updateQueue; - if (null !== newState) { +function attachSuspenseRetryListeners(finishedWork) { + var thenables = finishedWork.updateQueue; + if (null !== thenables) { finishedWork.updateQueue = null; var retryCache = finishedWork.stateNode; null === retryCache && (retryCache = finishedWork.stateNode = new PossiblyWeakSet$1()); - newState.forEach(function(thenable) { + thenables.forEach(function(thenable) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); retryCache.has(thenable) || ((retry = tracing.unstable_wrap(retry)), @@ -5097,7 +5618,7 @@ function commitSuspenseComponent(finishedWork) { } var PossiblyWeakMap = "function" === typeof WeakMap ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; expirationTime.payload = { element: null }; var error = errorInfo.value; @@ -5108,7 +5629,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); + expirationTime = createUpdate(expirationTime, null); expirationTime.tag = 3; var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if ("function" === typeof getDerivedStateFromError) { @@ -5134,64 +5655,29 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { }); return expirationTime; } -function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null; - case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw ReactError( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -2049) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: - return ( - (effectTag = workInProgress.effectTag), - effectTag & 2048 - ? ((workInProgress.effectTag = (effectTag & -2049) | 64), - workInProgress) - : null - ); - case 18: - return null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 19: - case 20: - return null; - default: - return null; - } -} var ceil = Math.ceil, ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - LegacyUnbatchedPhase = 2, - RenderPhase = 4, - CommitPhase = 5, + NoContext = 0, + LegacyUnbatchedContext = 8, + RenderContext = 16, + CommitContext = 32, RootIncomplete = 0, RootErrored = 1, RootSuspended = 2, - RootCompleted = 3, - workPhase = 0, + RootSuspendedWithDelay = 3, + RootCompleted = 4, + executionContext = NoContext, workInProgressRoot = null, workInProgress = null, renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, - workInProgressRootMostRecentEventTime = 1073741823, + workInProgressRootLatestProcessedExpirationTime = 1073741823, + workInProgressRootLatestSuspenseTimeout = 1073741823, + workInProgressRootCanSuspendUsingConfig = null, + workInProgressRootHasPendingPing = !1, + globalMostRecentFallbackTime = 0, + FALLBACK_THROTTLE_MS = 500, nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, @@ -5202,36 +5688,52 @@ var ceil = Math.ceil, rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, + spawnedWorkDuringRender = null, currentEventTime = 0; function requestCurrentTime() { - return workPhase === RenderPhase || workPhase === CommitPhase - ? 1073741822 - ((now() / 10) | 0) + return (executionContext & (RenderContext | CommitContext)) !== NoContext + ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime ? currentEventTime - : (currentEventTime = 1073741822 - ((now() / 10) | 0)); -} -function computeExpirationForFiber(currentTime, fiber) { - if (0 === (fiber.mode & 1)) return 1073741823; - if (workPhase === RenderPhase) return renderExpirationTime; - switch (getCurrentPriorityLevel()) { - case 99: - currentTime = 1073741823; - break; - case 98: - currentTime = - 1073741822 - 10 * ((((1073741822 - currentTime + 15) / 10) | 0) + 1); - break; - case 97: - case 96: - currentTime = - 1073741822 - 25 * ((((1073741822 - currentTime + 500) / 25) | 0) + 1); - break; - case 95: - currentTime = 1; - break; - default: - throw ReactError("Expected a valid priority level"); - } + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); +} +function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { + fiber = fiber.mode; + if (0 === (fiber & 2)) return 1073741823; + var priorityLevel = getCurrentPriorityLevel(); + if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; + if ((executionContext & RenderContext) !== NoContext) + return renderExpirationTime; + if (null !== suspenseConfig) + currentTime = + 1073741821 - + 25 * + ((((1073741821 - + currentTime + + (suspenseConfig.timeoutMs | 0 || 5e3) / 10) / + 25) | + 0) + + 1); + else + switch (priorityLevel) { + case 99: + currentTime = 1073741823; + break; + case 98: + currentTime = + 1073741821 - 10 * ((((1073741821 - currentTime + 15) / 10) | 0) + 1); + break; + case 97: + case 96: + currentTime = + 1073741821 - 25 * ((((1073741821 - currentTime + 500) / 25) | 0) + 1); + break; + case 95: + currentTime = 1; + break; + default: + throw ReactError(Error("Expected a valid priority level")); + } null !== workInProgressRoot && currentTime === renderExpirationTime && --currentTime; @@ -5242,33 +5744,42 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), ReactError( - "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + Error( + "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." + ) )); fiber = markUpdateTimeFromFiberToRoot(fiber, expirationTime); - if (null !== fiber) - if (((fiber.pingTime = 0), 1073741823 === expirationTime)) - if (workPhase === LegacyUnbatchedPhase) + if (null !== fiber) { + fiber.pingTime = 0; + var priorityLevel = getCurrentPriorityLevel(); + if (1073741823 === expirationTime) + if ( + (executionContext & LegacyUnbatchedContext) !== NoContext && + (executionContext & (RenderContext | CommitContext)) === NoContext + ) { + scheduleInteractions( + fiber, + expirationTime, + tracing.__interactionsRef.current + ); for ( - expirationTime = renderRoot(fiber, 1073741823, !0); - null !== expirationTime; + var callback = renderRoot(fiber, 1073741823, !0); + null !== callback; ) - expirationTime = expirationTime(!0); - else + callback = callback(!0); + } else scheduleCallbackForRoot(fiber, 99, 1073741823), - 0 === workPhase && flushImmediateQueue(); - else { - var priorityLevel = getCurrentPriorityLevel(); - if (98 === priorityLevel) - if (null === rootsWithPendingDiscreteUpdates) - rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]]); - else { - var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(fiber); - (void 0 === lastDiscreteTime || lastDiscreteTime > expirationTime) && - rootsWithPendingDiscreteUpdates.set(fiber, expirationTime); - } - scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); - } + executionContext === NoContext && flushSyncCallbackQueue(); + else scheduleCallbackForRoot(fiber, priorityLevel, expirationTime); + (executionContext & 4) === NoContext || + (98 !== priorityLevel && 99 !== priorityLevel) || + (null === rootsWithPendingDiscreteUpdates + ? (rootsWithPendingDiscreteUpdates = new Map([[fiber, expirationTime]])) + : ((priorityLevel = rootsWithPendingDiscreteUpdates.get(fiber)), + (void 0 === priorityLevel || priorityLevel > expirationTime) && + rootsWithPendingDiscreteUpdates.set(fiber, expirationTime))); + } } function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { fiber.expirationTime < expirationTime && @@ -5309,23 +5820,30 @@ function scheduleCallbackForRoot(root, priorityLevel, expirationTime) { existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode); root.callbackExpirationTime = expirationTime; - existingCallbackNode = null; - 1073741823 !== expirationTime && - 1 !== expirationTime && - ((existingCallbackNode = 10 * (1073741822 - expirationTime) - now()), - 5e3 < existingCallbackNode && (existingCallbackNode = 5e3), - (existingCallbackNode = { timeout: existingCallbackNode })); - root.callbackNode = scheduleCallback( - priorityLevel, - runRootCallback.bind( - null, - root, - renderRoot.bind(null, root, expirationTime) - ), - existingCallbackNode - ); + 1073741823 === expirationTime + ? (root.callbackNode = scheduleSyncCallback( + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ) + )) + : ((existingCallbackNode = null), + 1 !== expirationTime && + (existingCallbackNode = { + timeout: 10 * (1073741821 - expirationTime) - now() + }), + (root.callbackNode = scheduleCallback( + priorityLevel, + runRootCallback.bind( + null, + root, + renderRoot.bind(null, root, expirationTime) + ), + existingCallbackNode + ))); } - schedulePendingInteraction(root, expirationTime); + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); } function runRootCallback(root, callback, isSync) { var prevCallbackNode = root.callbackNode, @@ -5348,9 +5866,7 @@ function resolveLocksOnRoot(root, expirationTime) { return null !== firstBatch && firstBatch._defer && firstBatch._expirationTime >= expirationTime - ? ((root.finishedWork = root.current.alternate), - (root.pendingCommitExpirationTime = expirationTime), - scheduleCallback(97, function() { + ? (scheduleCallback(97, function() { firstBatch._onComplete(); return null; }), @@ -5362,13 +5878,14 @@ function flushPendingDiscreteUpdates() { var roots = rootsWithPendingDiscreteUpdates; rootsWithPendingDiscreteUpdates = null; roots.forEach(function(expirationTime, root) { - scheduleCallback(99, renderRoot.bind(null, root, expirationTime)); + scheduleSyncCallback(renderRoot.bind(null, root, expirationTime)); }); - flushImmediateQueue(); + flushSyncCallbackQueue(); } } function prepareFreshStack(root, expirationTime) { - root.pendingCommitExpirationTime = 0; + root.finishedWork = null; + root.finishedExpirationTime = 0; var timeoutHandle = root.timeoutHandle; -1 !== timeoutHandle && ((root.timeoutHandle = -1), cancelTimeout(timeoutHandle)); @@ -5392,6 +5909,12 @@ function prepareFreshStack(root, expirationTime) { case 4: popHostContainer(interruptedWork); break; + case 13: + pop(suspenseStackCursor, interruptedWork); + break; + case 19: + pop(suspenseStackCursor, interruptedWork); + break; case 10: popProvider(interruptedWork); } @@ -5401,27 +5924,35 @@ function prepareFreshStack(root, expirationTime) { workInProgress = createWorkInProgress(root.current, null, expirationTime); renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; - workInProgressRootMostRecentEventTime = 1073741823; + workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; + workInProgressRootCanSuspendUsingConfig = null; + workInProgressRootHasPendingPing = !1; + spawnedWorkDuringRender = null; } function renderRoot(root$jscomp$0, expirationTime, isSync) { - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); if (root$jscomp$0.firstPendingTime < expirationTime) return null; - if (root$jscomp$0.pendingCommitExpirationTime === expirationTime) - return ( - (root$jscomp$0.pendingCommitExpirationTime = 0), - commitRoot.bind(null, root$jscomp$0, expirationTime) - ); + if (isSync && root$jscomp$0.finishedExpirationTime === expirationTime) + return commitRoot.bind(null, root$jscomp$0); flushPassiveEffects(); if ( root$jscomp$0 !== workInProgressRoot || expirationTime !== renderExpirationTime ) prepareFreshStack(root$jscomp$0, expirationTime), - startWorkOnPendingInteraction(root$jscomp$0, expirationTime); + startWorkOnPendingInteractions(root$jscomp$0, expirationTime); + else if (workInProgressRootExitStatus === RootSuspendedWithDelay) + if (workInProgressRootHasPendingPing) + prepareFreshStack(root$jscomp$0, expirationTime); + else { + var lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + } if (null !== workInProgress) { - var prevWorkPhase = workPhase; - workPhase = RenderPhase; + lastPendingTime = executionContext; + executionContext |= RenderContext; var prevDispatcher = ReactCurrentDispatcher.current; null === prevDispatcher && (prevDispatcher = ContextOnlyDispatcher); ReactCurrentDispatcher.current = ContextOnlyDispatcher; @@ -5432,8 +5963,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { var currentTime = requestCurrentTime(); if (currentTime < expirationTime) return ( - (workPhase = prevWorkPhase), - resetContextDependences(), + (executionContext = lastPendingTime), + resetContextDependencies(), (ReactCurrentDispatcher.current = prevDispatcher), (tracing.__interactionsRef.current = prevInteractions), renderRoot.bind(null, root$jscomp$0, currentTime) @@ -5450,14 +5981,14 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = performUnitOfWork(workInProgress); break; } catch (thrownValue) { - resetContextDependences(); + resetContextDependencies(); resetHooks(); currentTime = workInProgress; if (null === currentTime || null === currentTime.return) throw (prepareFreshStack(root$jscomp$0, expirationTime), - (workPhase = prevWorkPhase), + (executionContext = lastPendingTime), thrownValue); - currentTime.mode & 4 && + currentTime.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(currentTime, !0); a: { var root = root$jscomp$0, @@ -5472,29 +6003,41 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; + var thenable = value, + hasInvisibleParentBoundary = + 0 !== + (suspenseStackCursor.current & InvisibleParentSuspenseContext); value = returnFiber; do { - if ( - 13 === value.tag && - (void 0 === value.memoizedProps.fallback - ? 0 - : null === value.memoizedState) - ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === value.tag)) + null !== value.memoizedState + ? (JSCompiler_temp = !1) + : ((JSCompiler_temp = value.memoizedProps), + (JSCompiler_temp = + void 0 === JSCompiler_temp.fallback + ? !1 + : !0 !== JSCompiler_temp.unstable_avoidThisFallback + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0)); + if (JSCompiler_temp) { returnFiber = value.updateQueue; null === returnFiber ? ((returnFiber = new Set()), returnFiber.add(thenable), (value.updateQueue = returnFiber)) : returnFiber.add(thenable); - if (0 === (value.mode & 1)) { + if (0 === (value.mode & 2)) { value.effectTag |= 64; sourceFiber.effectTag &= -1957; 1 === sourceFiber.tag && (null === sourceFiber.alternate ? (sourceFiber.tag = 17) : ((renderExpirationTime$jscomp$0 = createUpdate( - 1073741823 + 1073741823, + null )), (renderExpirationTime$jscomp$0.tag = 2), enqueueUpdate( @@ -5506,15 +6049,15 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { } sourceFiber = root; root = renderExpirationTime$jscomp$0; - var pingCache = sourceFiber.pingCache; - null === pingCache - ? ((pingCache = sourceFiber.pingCache = new PossiblyWeakMap()), + hasInvisibleParentBoundary = sourceFiber.pingCache; + null === hasInvisibleParentBoundary + ? ((hasInvisibleParentBoundary = sourceFiber.pingCache = new PossiblyWeakMap()), (returnFiber = new Set()), - pingCache.set(thenable, returnFiber)) - : ((returnFiber = pingCache.get(thenable)), + hasInvisibleParentBoundary.set(thenable, returnFiber)) + : ((returnFiber = hasInvisibleParentBoundary.get(thenable)), void 0 === returnFiber && ((returnFiber = new Set()), - pingCache.set(thenable, returnFiber))); + hasInvisibleParentBoundary.set(thenable, returnFiber))); returnFiber.has(root) || (returnFiber.add(root), (sourceFiber = pingSuspendedRoot.bind( @@ -5537,11 +6080,8 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { getStackByFiberInDevAndProd(sourceFiber) ); } - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootErrored; + workInProgressRootExitStatus !== RootCompleted && + (workInProgressRootExitStatus = RootErrored); value = createCapturedValue(value, sourceFiber); sourceFiber = returnFiber; do { @@ -5593,80 +6133,148 @@ function renderRoot(root$jscomp$0, expirationTime, isSync) { workInProgress = completeUnitOfWork(currentTime); } while (1); - workPhase = prevWorkPhase; - resetContextDependences(); + executionContext = lastPendingTime; + resetContextDependencies(); ReactCurrentDispatcher.current = prevDispatcher; tracing.__interactionsRef.current = prevInteractions; if (null !== workInProgress) return renderRoot.bind(null, root$jscomp$0, expirationTime); } + root$jscomp$0.finishedWork = root$jscomp$0.current.alternate; + root$jscomp$0.finishedExpirationTime = expirationTime; if (resolveLocksOnRoot(root$jscomp$0, expirationTime)) return null; workInProgressRoot = null; switch (workInProgressRootExitStatus) { case RootIncomplete: - throw ReactError("Should have a work-in-progress."); + throw ReactError(Error("Should have a work-in-progress.")); case RootErrored: return ( - (prevWorkPhase = root$jscomp$0.lastPendingTime), - root$jscomp$0.lastPendingTime < expirationTime - ? renderRoot.bind(null, root$jscomp$0, prevWorkPhase) + (lastPendingTime = root$jscomp$0.lastPendingTime), + lastPendingTime < expirationTime + ? renderRoot.bind(null, root$jscomp$0, lastPendingTime) : isSync - ? commitRoot.bind(null, root$jscomp$0, expirationTime) + ? commitRoot.bind(null, root$jscomp$0) : (prepareFreshStack(root$jscomp$0, expirationTime), - scheduleCallback( - 99, + scheduleSyncCallback( renderRoot.bind(null, root$jscomp$0, expirationTime) ), null) ); case RootSuspended: + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + !isSync && + ((isSync = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < isSync) + ) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); + lastPendingTime = root$jscomp$0.lastPendingTime; + if (lastPendingTime < expirationTime) + return renderRoot.bind(null, root$jscomp$0, lastPendingTime); + root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + isSync + ); + return null; + } + return commitRoot.bind(null, root$jscomp$0); + case RootSuspendedWithDelay: if (!isSync) { + if (workInProgressRootHasPendingPing) + return ( + prepareFreshStack(root$jscomp$0, expirationTime), + renderRoot.bind(null, root$jscomp$0, expirationTime) + ); isSync = root$jscomp$0.lastPendingTime; - if (root$jscomp$0.lastPendingTime < expirationTime) + if (isSync < expirationTime) return renderRoot.bind(null, root$jscomp$0, isSync); - if ( - 1073741823 !== workInProgressRootMostRecentEventTime && - ((prevWorkPhase = - 10 * (1073741822 - workInProgressRootMostRecentEventTime) - 5e3), - (isSync = now()), - (prevWorkPhase = isSync - prevWorkPhase), - (prevWorkPhase = - (120 > prevWorkPhase - ? 120 - : 480 > prevWorkPhase - ? 480 - : 1080 > prevWorkPhase - ? 1080 - : 1920 > prevWorkPhase - ? 1920 - : 3e3 > prevWorkPhase - ? 3e3 - : 4320 > prevWorkPhase - ? 4320 - : 1960 * ceil(prevWorkPhase / 1960)) - prevWorkPhase), - (isSync = 10 * (1073741822 - expirationTime) - isSync), - isSync < prevWorkPhase && (prevWorkPhase = isSync), - (isSync = prevWorkPhase), - 10 < isSync) - ) + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (isSync = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (isSync = 0) + : ((isSync = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (lastPendingTime = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - lastPendingTime), + (isSync = lastPendingTime - isSync), + 0 > isSync && (isSync = 0), + (isSync = + (120 > isSync + ? 120 + : 480 > isSync + ? 480 + : 1080 > isSync + ? 1080 + : 1920 > isSync + ? 1920 + : 3e3 > isSync + ? 3e3 + : 4320 > isSync + ? 4320 + : 1960 * ceil(isSync / 1960)) - isSync), + expirationTime < isSync && (isSync = expirationTime)); + if (10 < isSync) return ( (root$jscomp$0.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root$jscomp$0, expirationTime), + commitRoot.bind(null, root$jscomp$0), isSync )), null ); } - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return commitRoot.bind(null, root$jscomp$0); case RootCompleted: - return commitRoot.bind(null, root$jscomp$0, expirationTime); + return !isSync && + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig && + ((lastPendingTime = workInProgressRootLatestProcessedExpirationTime), + (prevDispatcher = workInProgressRootCanSuspendUsingConfig), + (expirationTime = prevDispatcher.busyMinDurationMs | 0), + 0 >= expirationTime + ? (expirationTime = 0) + : ((isSync = prevDispatcher.busyDelayMs | 0), + (lastPendingTime = + now() - + (10 * (1073741821 - lastPendingTime) - + (prevDispatcher.timeoutMs | 0 || 5e3))), + (expirationTime = + lastPendingTime <= isSync + ? 0 + : isSync + expirationTime - lastPendingTime)), + 10 < expirationTime) + ? ((root$jscomp$0.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root$jscomp$0), + expirationTime + )), + null) + : commitRoot.bind(null, root$jscomp$0); default: - throw ReactError("Unknown root exit status."); + throw ReactError(Error("Unknown root exit status.")); } } +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 1 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 1 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} function performUnitOfWork(unitOfWork) { var current$$1 = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 4) + 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), @@ -5683,7 +6291,7 @@ function completeUnitOfWork(unitOfWork) { var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 1024)) { - if (0 === (workInProgress.mode & 4)) + if (0 === (workInProgress.mode & 8)) current$$1 = completeWork( current$$1, workInProgress, @@ -5703,7 +6311,7 @@ function completeUnitOfWork(unitOfWork) { fiber = workInProgress; if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; - if (0 !== (fiber.mode & 4)) { + if (0 !== (fiber.mode & 8)) { for ( var actualDuration = fiber.actualDuration, treeBaseDuration = fiber.selfBaseDuration, @@ -5755,7 +6363,7 @@ function completeUnitOfWork(unitOfWork) { (unitOfWork.lastEffect = workInProgress))); } else { current$$1 = unwindWork(workInProgress, renderExpirationTime); - if (0 !== (workInProgress.mode & 4)) { + if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; for ( @@ -5781,8 +6389,8 @@ function completeUnitOfWork(unitOfWork) { (workInProgressRootExitStatus = RootCompleted); return null; } -function commitRoot(root, expirationTime) { - runWithPriority(99, commitRootImpl.bind(null, root, expirationTime)); +function commitRoot(root) { + runWithPriority(99, commitRootImpl.bind(null, root)); null !== rootWithPendingPassiveEffects && ((root = getCurrentPriorityLevel()), scheduleCallback(root, function() { @@ -5791,13 +6399,21 @@ function commitRoot(root, expirationTime) { })); return null; } -function commitRootImpl(root, expirationTime) { +function commitRootImpl(root) { flushPassiveEffects(); - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Should not already be working."); - var finishedWork = root.current.alternate; - if (null === finishedWork) - throw ReactError("Should have a work-in-progress root."); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError(Error("Should not already be working.")); + var finishedWork = root.finishedWork, + expirationTime = root.finishedExpirationTime; + if (null === finishedWork) return null; + root.finishedWork = null; + root.finishedExpirationTime = 0; + if (finishedWork === root.current) + throw ReactError( + Error( + "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." + ) + ); root.callbackNode = null; root.callbackExpirationTime = 0; var updateExpirationTimeBeforeCommit = finishedWork.expirationTime, @@ -5811,19 +6427,19 @@ function commitRootImpl(root, expirationTime) { (root.lastPendingTime = updateExpirationTimeBeforeCommit); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); - if (1 < finishedWork.effectTag) - if (null !== finishedWork.lastEffect) { - finishedWork.lastEffect.nextEffect = finishedWork; - var firstEffect = finishedWork.firstEffect; - } else firstEffect = finishedWork; - else firstEffect = finishedWork.firstEffect; - if (null !== firstEffect) { - updateExpirationTimeBeforeCommit = workPhase; - workPhase = CommitPhase; - childExpirationTimeBeforeCommit = tracing.__interactionsRef.current; + 1 < finishedWork.effectTag + ? null !== finishedWork.lastEffect + ? ((finishedWork.lastEffect.nextEffect = finishedWork), + (updateExpirationTimeBeforeCommit = finishedWork.firstEffect)) + : (updateExpirationTimeBeforeCommit = finishedWork) + : (updateExpirationTimeBeforeCommit = finishedWork.firstEffect); + if (null !== updateExpirationTimeBeforeCommit) { + childExpirationTimeBeforeCommit = executionContext; + executionContext |= CommitContext; + var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; ReactCurrentOwner$2.current = null; - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5866,11 +6482,12 @@ function commitRootImpl(root, expirationTime) { case 6: case 4: case 17: - case 20: break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -5878,13 +6495,13 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); commitTime = now$1(); - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for (; null !== nextEffect; ) { @@ -5919,24 +6536,26 @@ function commitRootImpl(root, expirationTime) { current$$1.child = null; current$$1.memoizedState = null; current$$1.updateQueue = null; + current$$1.dependencies = null; var alternate = current$$1.alternate; null !== alternate && ((alternate.return = null), (alternate.child = null), (alternate.memoizedState = null), - (alternate.updateQueue = null)); + (alternate.updateQueue = null), + (alternate.dependencies = null)); } nextEffect = nextEffect.nextEffect; } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); root.current = finishedWork; - nextEffect = firstEffect; + nextEffect = updateExpirationTimeBeforeCommit; do try { for ( @@ -6012,26 +6631,27 @@ function commitRootImpl(root, expirationTime) { break; case 12: var onRender = currentRef.memoizedProps.onRender; - onRender( - currentRef.memoizedProps.id, - null === current$$1$jscomp$1 ? "mount" : "update", - currentRef.actualDuration, - currentRef.treeBaseDuration, - currentRef.actualStartTime, - commitTime, - current$$1.memoizedInteractions - ); + "function" === typeof onRender && + onRender( + currentRef.memoizedProps.id, + null === current$$1$jscomp$1 ? "mount" : "update", + currentRef.actualDuration, + currentRef.treeBaseDuration, + currentRef.actualStartTime, + commitTime, + current$$1.memoizedInteractions + ); break; case 13: + case 19: case 17: - break; case 20: break; - case 19: - break; default: throw ReactError( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + 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." + ) ); } } @@ -6056,32 +6676,51 @@ function commitRootImpl(root, expirationTime) { } } catch (error) { if (null === nextEffect) - throw ReactError("Should be working on an effect."); + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(nextEffect, error); nextEffect = nextEffect.nextEffect; } while (null !== nextEffect); nextEffect = null; - tracing.__interactionsRef.current = childExpirationTimeBeforeCommit; - workPhase = updateExpirationTimeBeforeCommit; + requestPaint(); + tracing.__interactionsRef.current = prevInteractions; + executionContext = childExpirationTimeBeforeCommit; } else (root.current = finishedWork), (commitTime = now$1()); - rootDoesHavePassiveEffects - ? ((rootDoesHavePassiveEffects = !1), + if ((effectTag$jscomp$0 = rootDoesHavePassiveEffects)) + (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsExpirationTime = expirationTime)) - : finishPendingInteractions(root, expirationTime); - expirationTime = root.firstPendingTime; - 0 !== expirationTime - ? ((effectTag$jscomp$0 = requestCurrentTime()), - (effectTag$jscomp$0 = inferPriorityFromExpirationTime( - effectTag$jscomp$0, - expirationTime - )), - scheduleCallbackForRoot(root, effectTag$jscomp$0, expirationTime)) - : (legacyErrorBoundariesThatAlreadyFailed = null); + (pendingPassiveEffectsExpirationTime = expirationTime); + else + for (nextEffect = updateExpirationTimeBeforeCommit; null !== nextEffect; ) + (current$$1$jscomp$1 = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + (nextEffect = current$$1$jscomp$1); + current$$1$jscomp$1 = root.firstPendingTime; + if (0 !== current$$1$jscomp$1) { + instance$jscomp$0 = requestCurrentTime(); + instance$jscomp$0 = inferPriorityFromExpirationTime( + instance$jscomp$0, + current$$1$jscomp$1 + ); + if (null !== spawnedWorkDuringRender) + for ( + prevProps$jscomp$0 = spawnedWorkDuringRender, + spawnedWorkDuringRender = null, + updateQueue = 0; + updateQueue < prevProps$jscomp$0.length; + updateQueue++ + ) + scheduleInteractions( + root, + prevProps$jscomp$0[updateQueue], + root.memoizedInteractions + ); + scheduleCallbackForRoot(root, instance$jscomp$0, current$$1$jscomp$1); + } else legacyErrorBoundariesThatAlreadyFailed = null; + effectTag$jscomp$0 || finishPendingInteractions(root, expirationTime); "function" === typeof onCommitFiberRoot && - onCommitFiberRoot(finishedWork.stateNode); - 1073741823 === expirationTime + onCommitFiberRoot(finishedWork.stateNode, expirationTime); + 1073741823 === current$$1$jscomp$1 ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) @@ -6091,8 +6730,8 @@ function commitRootImpl(root, expirationTime) { (root = firstUncaughtError), (firstUncaughtError = null), root); - if (workPhase === LegacyUnbatchedPhase) return null; - flushImmediateQueue(); + if ((executionContext & LegacyUnbatchedContext) !== NoContext) return null; + flushSyncCallbackQueue(); return null; } function flushPassiveEffects() { @@ -6103,25 +6742,36 @@ function flushPassiveEffects() { pendingPassiveEffectsExpirationTime = 0; var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; - if (workPhase === RenderPhase || workPhase === CommitPhase) - throw ReactError("Cannot flush passive effects while already rendering."); - var prevWorkPhase = workPhase; - workPhase = CommitPhase; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw ReactError( + Error("Cannot flush passive effects while already rendering.") + ); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; for (var effect = root.current.firstEffect; null !== effect; ) { try { var finishedWork = effect; - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + if (0 !== (finishedWork.effectTag & 512)) + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork), + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + } } catch (error) { - if (null === effect) throw ReactError("Should be working on an effect."); + if (null === effect) + throw ReactError(Error("Should be working on an effect.")); captureCommitPhaseError(effect, error); } - effect = effect.nextEffect; + finishedWork = effect.nextEffect; + effect.nextEffect = null; + effect = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); - workPhase = prevWorkPhase; - flushImmediateQueue(); + executionContext = prevExecutionContext; + flushSyncCallbackQueue(); return !0; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -6162,11 +6812,18 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); workInProgressRoot === root && renderExpirationTime === suspendedTime - ? prepareFreshStack(root, renderExpirationTime) + ? workInProgressRootExitStatus === RootSuspendedWithDelay || + (workInProgressRootExitStatus === RootSuspended && + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) + ? prepareFreshStack(root, renderExpirationTime) + : (workInProgressRootHasPendingPing = !0) : root.lastPendingTime < suspendedTime || ((thenable = root.pingTime), (0 !== thenable && thenable < suspendedTime) || ((root.pingTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), (thenable = requestCurrentTime()), (thenable = inferPriorityFromExpirationTime(thenable, suspendedTime)), scheduleCallbackForRoot(root, thenable, suspendedTime))); @@ -6175,7 +6832,7 @@ function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(thenable); retryCache = requestCurrentTime(); - thenable = computeExpirationForFiber(retryCache, boundaryFiber); + thenable = computeExpirationForFiber(retryCache, boundaryFiber, null); retryCache = inferPriorityFromExpirationTime(retryCache, thenable); boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && @@ -6228,6 +6885,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, renderExpirationTime ); + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( current$$1, workInProgress, @@ -6235,6 +6897,39 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); return null !== workInProgress ? workInProgress.sibling : null; } + push( + suspenseStackCursor, + suspenseStackCursor.current & SubtreeSuspenseContextMask, + workInProgress + ); + break; + case 19: + updateExpirationTime = 0 !== (current$$1.effectTag & 64); + if (workInProgress.childExpirationTime < renderExpirationTime) + return ( + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ), + updateExpirationTime && (workInProgress.effectTag |= 64), + null + ); + if (updateExpirationTime) + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + updateExpirationTime = workInProgress.memoizedState; + null !== updateExpirationTime && + ((updateExpirationTime.rendering = null), + (updateExpirationTime.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); } return bailoutOnAlreadyFinishedWork( current$$1, @@ -6370,9 +7065,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { break; default: throw ReactError( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." + Error( + "Element type is invalid. Received a promise that resolves to: " + + context + + ". Lazy element type must resolve to a class or function." + ) ); } return workInProgress; @@ -6413,7 +7110,9 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime = workInProgress.updateQueue; if (null === updateExpirationTime) throw ReactError( - "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." + 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." + ) ); context = workInProgress.memoizedState; context = null !== context ? context.element : null; @@ -6569,16 +7268,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== oldValue; ) { - var list = oldValue.contextDependencies; + var list = oldValue.dependencies; if (null !== list) { getDerivedStateFromProps = oldValue.child; - for (var dependency = list.first; null !== dependency; ) { + for ( + var dependency = list.firstContext; + null !== dependency; + + ) { if ( dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { 1 === oldValue.tag && - ((dependency = createUpdate(renderExpirationTime)), + ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), enqueueUpdate(oldValue, dependency)); oldValue.expirationTime < renderExpirationTime && @@ -6587,22 +7290,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); - dependency = renderExpirationTime; - for (var node = oldValue.return; null !== node; ) { - var alternate = node.alternate; - if (node.childExpirationTime < dependency) - (node.childExpirationTime = dependency), - null !== alternate && - alternate.childExpirationTime < dependency && - (alternate.childExpirationTime = dependency); - else if ( - null !== alternate && - alternate.childExpirationTime < dependency - ) - alternate.childExpirationTime = dependency; - else break; - node = node.return; - } + scheduleWorkOnParentPath( + oldValue.return, + renderExpirationTime + ); list.expirationTime < renderExpirationTime && (list.expirationTime = renderExpirationTime); break; @@ -6729,13 +7420,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime ) ); + case 19: + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); } throw ReactError( - "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + Error( + "Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue." + ) ); }; -function schedulePendingInteraction(root, expirationTime) { - var interactions = tracing.__interactionsRef.current; +function scheduleInteractions(root, expirationTime, interactions) { if (0 < interactions.size) { var pendingInteractionMap = root.pendingInteractionMap, pendingInteractions = pendingInteractionMap.get(expirationTime); @@ -6756,7 +7454,7 @@ function schedulePendingInteraction(root, expirationTime) { ); } } -function startWorkOnPendingInteraction(root, expirationTime) { +function startWorkOnPendingInteractions(root, expirationTime) { var interactions = new Set(); root.pendingInteractionMap.forEach(function( scheduledInteractions, @@ -6820,6 +7518,34 @@ function finishPendingInteractions(root, committedExpirationTime) { }); } } +var onCommitFiberRoot = null, + onCommitFiberUnmount = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function injectInternals(internals) { + if ("undefined" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (hook.isDisabled || !hook.supportsFiber) return !0; + try { + var rendererID = hook.inject(internals); + onCommitFiberRoot = function(root, expirationTime) { + try { + var didError = 64 === (root.current.effectTag & 64), + currentTime = requestCurrentTime(), + priorityLevel = inferPriorityFromExpirationTime( + currentTime, + expirationTime + ); + hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError); + } catch (err) {} + }; + onCommitFiberUnmount = function(fiber) { + try { + hook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) {} + }; + } catch (err) {} + return !0; +} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -6827,7 +7553,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.index = 0; this.ref = null; this.pendingProps = pendingProps; - this.contextDependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; + this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; this.effectTag = 0; this.lastEffect = this.firstEffect = this.nextEffect = null; @@ -6881,7 +7607,16 @@ function createWorkInProgress(current, pendingProps) { workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; - workInProgress.contextDependencies = current.contextDependencies; + pendingProps = current.dependencies; + workInProgress.dependencies = + null === pendingProps + ? null + : { + expirationTime: pendingProps.expirationTime, + firstContext: pendingProps.firstContext, + listeners: pendingProps.listeners, + responders: pendingProps.responders + }; workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; @@ -6911,12 +7646,16 @@ function createFiberFromTypeAndProps( key ); case REACT_CONCURRENT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 3, expirationTime, key); + fiberTag = 8; + mode |= 7; + break; case REACT_STRICT_MODE_TYPE: - return createFiberFromMode(pendingProps, mode | 2, expirationTime, key); + fiberTag = 8; + mode |= 1; + break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -6925,8 +7664,15 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.elementType = REACT_SUSPENSE_TYPE), (type.type = REACT_SUSPENSE_TYPE), + (type.elementType = REACT_SUSPENSE_TYPE), + (type.expirationTime = expirationTime), + type + ); + case REACT_SUSPENSE_LIST_TYPE: + return ( + (type = createFiber(19, pendingProps, key, mode)), + (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type ); @@ -6951,9 +7697,11 @@ function createFiberFromTypeAndProps( break a; } throw ReactError( - "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - (null == type ? type : typeof type) + - "." + Error( + "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + + (null == type ? type : typeof type) + + "." + ) ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -6967,14 +7715,6 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { elements.expirationTime = expirationTime; return elements; } -function createFiberFromMode(pendingProps, mode, expirationTime, key) { - pendingProps = createFiber(8, pendingProps, key, mode); - mode = 0 === (mode & 1) ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; - pendingProps.elementType = mode; - pendingProps.type = mode; - pendingProps.expirationTime = expirationTime; - return pendingProps; -} function createFiberFromText(content, mode, expirationTime) { content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; @@ -6995,11 +7735,12 @@ function createFiberFromPortal(portal, mode, expirationTime) { }; return mode; } -function FiberRootNode(containerInfo, hydrate) { +function FiberRootNode(containerInfo, tag, hydrate) { + this.tag = tag; this.current = null; this.containerInfo = containerInfo; this.pingCache = this.pendingChildren = null; - this.pendingCommitExpirationTime = 0; + this.finishedExpirationTime = 0; this.finishedWork = null; this.timeoutHandle = -1; this.pendingContext = this.context = null; @@ -7014,10 +7755,12 @@ function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { if ("function" === typeof component.render) - throw ReactError("Unable to find node on an unmounted component."); + throw ReactError(Error("Unable to find node on an unmounted component.")); throw ReactError( - "Argument appears to not be a ReactComponent. Keys: " + - Object.keys(component) + Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ) ); } component = findCurrentHostFiber(fiber); @@ -7025,8 +7768,13 @@ function findHostInstance(component) { } function updateContainer(element, container, parentComponent, callback) { var current$$1 = container.current, - currentTime = requestCurrentTime(); - current$$1 = computeExpirationForFiber(currentTime, current$$1); + currentTime = requestCurrentTime(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + current$$1 = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); currentTime = container.current; a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; @@ -7036,7 +7784,9 @@ function updateContainer(element, container, parentComponent, callback) { 1 !== parentComponent.tag ) throw ReactError( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + 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 parentContext = parentComponent; do { @@ -7055,7 +7805,9 @@ function updateContainer(element, container, parentComponent, callback) { parentContext = parentContext.return; } while (null !== parentContext); throw ReactError( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ) ); } if (1 === parentComponent.tag) { @@ -7075,12 +7827,11 @@ function updateContainer(element, container, parentComponent, callback) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(current$$1); - callback.payload = { element: element }; + suspenseConfig = createUpdate(current$$1, suspenseConfig); + suspenseConfig.payload = { element: element }; container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - flushPassiveEffects(); - enqueueUpdate(currentTime, callback); + null !== container && (suspenseConfig.callback = container); + enqueueUpdate(currentTime, suspenseConfig); scheduleUpdateOnFiber(currentTime, current$$1); return current$$1; } @@ -7117,7 +7868,7 @@ function _inherits(subClass, superClass) { var getInspectorDataForViewTag = void 0; getInspectorDataForViewTag = function() { throw ReactError( - "getInspectorDataForViewTag() is not available in production" + Error("getInspectorDataForViewTag() is not available in production") ); }; function findNodeHandle(componentOrHandle) { @@ -7133,19 +7884,19 @@ function findNodeHandle(componentOrHandle) { ? componentOrHandle.canonical._nativeTag : componentOrHandle._nativeTag; } -_batchedUpdatesImpl = function(fn, a) { - if (0 !== workPhase) return fn(a); - workPhase = 1; +batchedUpdatesImpl = function(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= 1; try { return fn(a); } finally { - (workPhase = 0), flushImmediateQueue(); + (executionContext = prevExecutionContext), + executionContext === NoContext && flushSyncCallbackQueue(); } }; -_flushInteractiveUpdatesImpl = function() { - workPhase !== RenderPhase && - workPhase !== CommitPhase && - flushPendingDiscreteUpdates(); +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); }; var roots = new Map(), ReactNativeRenderer = { @@ -7259,6 +8010,14 @@ var roots = new Map(), })(React.Component); })(findNodeHandle, findHostInstance), findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + }, setNativeProps: function(handle, nativeProps) { null != handle._nativeTag && ((nativeProps = diffProperties( @@ -7277,9 +8036,9 @@ var roots = new Map(), render: function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { - root = new FiberRootNode(containerTag, !1); + root = new FiberRootNode(containerTag, 0, !1); var uninitializedFiber = 0; - isDevToolsPresent && (uninitializedFiber |= 4); + isDevToolsPresent && (uninitializedFiber |= 8); uninitializedFiber = createFiber(3, null, null, uninitializedFiber); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -7436,7 +8195,8 @@ var roots = new Map(), findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, - setRefreshHandler: null + setRefreshHandler: null, + getCurrentFiber: null }) ); })({ diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index acadc77985e04d..8f6a708fd20579 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -23,12 +23,6 @@ if (__DEV__) { ReactFabric = require('../implementations/ReactFabric-prod'); } -if (global.RN$Bridgeless) { - // TODO T47525605 Clean this up once stopSurface has been added - global.RN$stopSurface = - ReactFabric.stopSurface ?? ReactFabric.unmountComponentAtNode; -} else { - BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); -} +BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); module.exports = (ReactFabric: ReactNativeType); diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index 3e777114db2ae5..200bf86592b57d 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -131,6 +131,7 @@ type SecretInternalsFabricType = { export type ReactNativeType = { NativeComponent: typeof ReactNativeComponent, findNodeHandle(componentOrHandle: any): ?number, + dispatchCommand(handle: any, command: string, args: Array): void, setNativeProps(handle: any, nativeProps: Object): void, render( element: React$Element, @@ -147,6 +148,7 @@ export type ReactNativeType = { export type ReactFabricType = { NativeComponent: typeof ReactNativeComponent, findNodeHandle(componentOrHandle: any): ?number, + dispatchCommand(handle: any, command: string, args: Array): void, setNativeProps(handle: any, nativeProps: Object): void, render( element: React$Element, @@ -154,6 +156,82 @@ export type ReactFabricType = { callback: ?Function, ): any, unmountComponentAtNode(containerTag: number): any, - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: SecretInternalsFabricType, }; + +export type ReactNativeEventTarget = { + node: Object, + canonical: { + _nativeTag: number, + viewConfig: ReactNativeBaseComponentViewConfig<>, + currentProps: Object, + _internalInstanceHandle: Object, + }, +}; + +export type ReactFaricEventTouch = { + identifier: number, + locationX: number, + locationY: number, + pageX: number, + pageY: number, + screenX: number, + screenY: number, + target: number, + timestamp: number, + force: number, +}; + +export type ReactFaricEvent = { + touches: Array, + changedTouches: Array, + targetTouches: Array, + target: number, +}; + +export type ReactNativeResponderEvent = { + nativeEvent: ReactFaricEvent, + responderTarget: null | ReactNativeEventTarget, + target: null | ReactNativeEventTarget, + type: string, +}; + +export type ReactNativeResponderContext = { + dispatchEvent: ( + eventProp: string, + eventValue: any, + eventPriority: EventPriority, + ) => void, + isTargetWithinNode: ( + childTarget: ReactNativeEventTarget, + parentTarget: ReactNativeEventTarget, + ) => boolean, + getTargetBoundingRect( + target: ReactNativeEventTarget, + cb: ({ + left: number, + right: number, + top: number, + bottom: number, + }) => void, + ): void, + addRootEventTypes: (rootEventTypes: Array) => void, + removeRootEventTypes: (rootEventTypes: Array) => void, + setTimeout: (func: () => void, timeout: number) => number, + clearTimeout: (timerId: number) => void, + getTimeStamp: () => number, +}; + +export type PointerType = + | '' + | 'mouse' + | 'keyboard' + | 'pen' + | 'touch' + | 'trackpad'; + +export type EventPriority = 0 | 1 | 2; + +export const DiscreteEvent: EventPriority = 0; +export const UserBlockingEvent: EventPriority = 1; +export const ContinuousEvent: EventPriority = 2; diff --git a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js index c4d00585437137..5ebc0d36d39fee 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -8,6 +8,8 @@ * @flow strict-local */ +/* eslint-disable react-internal/warning-and-invariant-args */ + 'use strict'; import type { diff --git a/Libraries/Renderer/shims/ReactTypes.js b/Libraries/Renderer/shims/ReactTypes.js index 3fb4c46cea32df..74565344365f1c 100644 --- a/Libraries/Renderer/shims/ReactTypes.js +++ b/Libraries/Renderer/shims/ReactTypes.js @@ -13,9 +13,7 @@ export type ReactNode = | ReactText | ReactFragment | ReactProvider - | ReactConsumer - | ReactEventComponent - | ReactEventTarget; + | ReactConsumer; export type ReactEmpty = null | void | boolean; @@ -81,111 +79,81 @@ export type RefObject = {| current: any, |}; -export type ReactEventResponderEventType = - | string - | {name: string, passive?: boolean}; - -export type ReactEventResponder = { - targetEventTypes?: Array, - rootEventTypes?: Array, - createInitialState?: (props: null | Object) => Object, - stopLocalPropagation: boolean, - onEvent?: ( - event: ReactResponderEvent, - context: ReactResponderContext, - props: null | Object, - state: null | Object, - ) => void, - onEventCapture?: ( - event: ReactResponderEvent, - context: ReactResponderContext, - props: null | Object, - state: null | Object, - ) => void, - onRootEvent?: ( - event: ReactResponderEvent, - context: ReactResponderContext, - props: null | Object, - state: null | Object, - ) => void, - onMount?: ( - context: ReactResponderContext, - props: null | Object, - state: null | Object, - ) => void, - onUnmount?: ( - context: ReactResponderContext, - props: null | Object, - state: null | Object, - ) => void, - onOwnershipChange?: ( - context: ReactResponderContext, - props: null | Object, - state: null | Object, - ) => void, -}; - -export type ReactEventComponentInstance = {| - currentFiber: mixed, - props: null | Object, - responder: ReactEventResponder, +export type ReactEventResponderInstance = {| + fiber: Object, + props: Object, + responder: ReactEventResponder, rootEventTypes: null | Set, - rootInstance: mixed, - state: null | Object, -|}; - -export type ReactEventComponent = {| - $$typeof: Symbol | number, - displayName?: string, - props: null | Object, - responder: ReactEventResponder, + state: Object, + target: mixed, |}; -export type ReactEventTarget = {| +export type ReactEventResponder = { $$typeof: Symbol | number, - displayName?: string, - type: Symbol | number, -|}; + displayName: string, + targetEventTypes: null | Array, + rootEventTypes: null | Array, + getInitialState: null | ((props: Object) => Object), + onEvent: + | null + | ((event: E, context: C, props: Object, state: Object) => void), + onRootEvent: + | null + | ((event: E, context: C, props: Object, state: Object) => void), + onMount: null | ((context: C, props: Object, state: Object) => void), + onUnmount: null | ((context: C, props: Object, state: Object) => void), + onOwnershipChange: + | null + | ((context: C, props: Object, state: Object) => void), +}; -type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | Touch; +export type EventPriority = 0 | 1 | 2; -export type ReactResponderEvent = { - nativeEvent: AnyNativeEvent, - target: Element | Document, - type: string, - passive: boolean, - passiveSupported: boolean, -}; +export const DiscreteEvent: EventPriority = 0; +export const UserBlockingEvent: EventPriority = 1; +export const ContinuousEvent: EventPriority = 2; -export type ReactResponderDispatchEventOptions = { - discrete?: boolean, -}; +export type ReactFundamentalComponentInstance = {| + currentFiber: mixed, + instance: mixed, + prevProps: null | Object, + props: Object, + impl: ReactFundamentalImpl, + state: Object, +|}; -export type ReactResponderContext = { - dispatchEvent: ( - eventObject: Object, - listener: (Object) => void, - options: ReactResponderDispatchEventOptions, - ) => void, - isTargetWithinElement: ( - childTarget: Element | Document, - parentTarget: Element | Document, +export type ReactFundamentalImpl = { + displayName: string, + reconcileChildren: boolean, + getInitialState?: (props: Object) => Object, + getInstance: (context: C, props: Object, state: Object) => H, + getServerSideString?: (context: C, props: Object) => string, + getServerSideStringClose?: (context: C, props: Object) => string, + onMount: (context: C, instance: mixed, props: Object, state: Object) => void, + shouldUpdate?: ( + context: C, + prevProps: null | Object, + nextProps: Object, + state: Object, ) => boolean, - isTargetWithinEventComponent: (Element | Document) => boolean, - isTargetWithinEventResponderScope: (Element | Document) => boolean, - isPositionWithinTouchHitTarget: (x: number, y: number) => boolean, - addRootEventTypes: ( - rootEventTypes: Array, + onUpdate?: ( + context: C, + instance: mixed, + prevProps: null | Object, + nextProps: Object, + state: Object, ) => void, - removeRootEventTypes: ( - rootEventTypes: Array, + onUnmount?: ( + context: C, + instance: mixed, + props: Object, + state: Object, ) => void, - hasOwnership: () => boolean, - requestResponderOwnership: () => boolean, - requestGlobalOwnership: () => boolean, - releaseOwnership: () => boolean, - setTimeout: (func: () => void, timeout: number) => Symbol, - clearTimeout: (timerId: Symbol) => void, - getFocusableElementsInScope(): Array, - getActiveDocument(): Document, + onHydrate?: (context: C, props: Object, state: Object) => boolean, + onFocus?: (context: C, props: Object, state: Object) => boolean, }; + +export type ReactFundamentalComponent = {| + $$typeof: Symbol | number, + impl: ReactFundamentalImpl, +|};