diff --git a/.circleci/config.yml b/.circleci/config.yml index dc1337a2e107e0..ef5859daf45890 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,7 +51,7 @@ executors: reactnativeios: <<: *defaults macos: - xcode: &_XCODE_VERSION "12.1.0" + xcode: &_XCODE_VERSION "12.4.0" # ------------------------- # COMMANDS diff --git a/.editorconfig b/.editorconfig index 45dc2a9a3fecd4..2e8c85b97387b5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -15,3 +15,7 @@ indent_size = 4 [BUCK] indent_size = 4 + +# Windows files +[*.bat] +end_of_line = crlf diff --git a/.flowconfig b/.flowconfig index 01dcce1eb86ed6..910acf0454d964 100644 --- a/.flowconfig +++ b/.flowconfig @@ -31,6 +31,8 @@ emoji=true exact_by_default=true +format.bracket_spacing=false + module.file_ext=.js module.file_ext=.json module.file_ext=.ios.js @@ -68,4 +70,4 @@ untyped-import untyped-type-import [version] -^0.148.0 +^0.152.0 diff --git a/.flowconfig.android b/.flowconfig.android index 48daf51de417ff..03c4c388e5909e 100644 --- a/.flowconfig.android +++ b/.flowconfig.android @@ -31,6 +31,8 @@ emoji=true exact_by_default=true +format.bracket_spacing=false + module.file_ext=.js module.file_ext=.json module.file_ext=.android.js @@ -68,4 +70,4 @@ untyped-import untyped-type-import [version] -^0.148.0 +^0.152.0 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000000..45a3dcb2a20316 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Windows files should use crlf line endings +# https://help.github.com/articles/dealing-with-line-endings/ +*.bat text eol=crlf diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5aad570ec84190..2227d0c7930c59 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,6 +86,7 @@ The process of proposing a change to React Native can be summarized as follows: 8. Create a pull request to the React Native repository. 9. Review and address comments on your pull request. 1. A bot may comment with suggestions. Generally we ask you to resolve these first before a maintainer will review your code. + 2. If changes are requested and addressed, please [request review](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review) to notify reviewers to take another look. 10. If you haven't already, please complete the [Contributor License Agreement](https://github.com/facebook/react-native/wiki/Contributor-License-Agreement) ("CLA"). **[Complete your CLA here.](https://code.facebook.com/cla)** If all goes well, your pull request will be merged. If it is not merged, maintainers will do their best to explain the reason why. diff --git a/IntegrationTests/GlobalEvalWithSourceUrlTest.js b/IntegrationTests/GlobalEvalWithSourceUrlTest.js index fca7bfbc2170c7..a69ee3728c48b0 100644 --- a/IntegrationTests/GlobalEvalWithSourceUrlTest.js +++ b/IntegrationTests/GlobalEvalWithSourceUrlTest.js @@ -10,7 +10,7 @@ 'use strict'; -import type {ExtendedError} from 'react-native/Libraries/Core/Devtools/parseErrorStack'; +import type {ExtendedError} from 'react-native/Libraries/Core/ExtendedError'; const React = require('react'); const ReactNative = require('react-native'); diff --git a/Libraries/Animated/AnimatedImplementation.js b/Libraries/Animated/AnimatedImplementation.js index 12b225abab0616..706b87ea01e9e1 100644 --- a/Libraries/Animated/AnimatedImplementation.js +++ b/Libraries/Animated/AnimatedImplementation.js @@ -706,6 +706,4 @@ module.exports = { * Expose Event class, so it can be used as a type for type checkers. */ Event: AnimatedEvent, - - __PropsOnlyForTests: AnimatedProps, }; diff --git a/Libraries/Animated/AnimatedMock.js b/Libraries/Animated/AnimatedMock.js index eecfbb884ec42b..50e69439a50453 100644 --- a/Libraries/Animated/AnimatedMock.js +++ b/Libraries/Animated/AnimatedMock.js @@ -152,5 +152,4 @@ module.exports = { forkEvent: AnimatedImplementation.forkEvent, unforkEvent: AnimatedImplementation.unforkEvent, Event: AnimatedEvent, - __PropsOnlyForTests: AnimatedProps, }; diff --git a/Libraries/Animated/__tests__/Animated-test.js b/Libraries/Animated/__tests__/Animated-test.js index f7a8bb05ace086..2b2ffe04dfdfb8 100644 --- a/Libraries/Animated/__tests__/Animated-test.js +++ b/Libraries/Animated/__tests__/Animated-test.js @@ -8,6 +8,7 @@ * @emails oncall+react_native */ +import AnimatedProps from '../nodes/AnimatedProps'; import TestRenderer from 'react-test-renderer'; import * as React from 'react'; @@ -21,6 +22,7 @@ jest.mock('../../BatchedBridge/NativeModules', () => ({ })); let Animated = require('../Animated'); + describe('Animated tests', () => { beforeEach(() => { jest.resetModules(); @@ -32,7 +34,7 @@ describe('Animated tests', () => { const callback = jest.fn(); - const node = new Animated.__PropsOnlyForTests( + const node = new AnimatedProps( { style: { backgroundColor: 'red', @@ -55,8 +57,6 @@ describe('Animated tests', () => { callback, ); - expect(anim.__getChildren().length).toBe(3); - expect(node.__getValue()).toEqual({ style: { backgroundColor: 'red', @@ -69,6 +69,12 @@ describe('Animated tests', () => { }, }); + expect(anim.__getChildren().length).toBe(0); + + node.__attach(); + + expect(anim.__getChildren().length).toBe(3); + anim.setValue(0.5); expect(callback).toBeCalled(); @@ -786,7 +792,7 @@ describe('Animated tests', () => { const callback = jest.fn(); - const node = new Animated.__PropsOnlyForTests( + const node = new AnimatedProps( { style: { opacity: vec.x.interpolate({ @@ -809,6 +815,10 @@ describe('Animated tests', () => { }, }); + node.__attach(); + + expect(callback.mock.calls.length).toBe(0); + vec.setValue({x: 42, y: 1492}); expect(callback.mock.calls.length).toBe(2); // once each for x, y @@ -890,7 +900,7 @@ describe('Animated tests', () => { const value3 = new Animated.Value(0); const value4 = Animated.add(value3, Animated.multiply(value1, value2)); const callback = jest.fn(); - const view = new Animated.__PropsOnlyForTests( + const view = new AnimatedProps( { style: { transform: [ @@ -902,6 +912,7 @@ describe('Animated tests', () => { }, callback, ); + view.__attach(); const listener = jest.fn(); const id = value4.addListener(listener); value3.setValue(137); diff --git a/Libraries/Animated/createAnimatedComponent.js b/Libraries/Animated/createAnimatedComponent.js index fda18f0af80744..add2f211350bc3 100644 --- a/Libraries/Animated/createAnimatedComponent.js +++ b/Libraries/Animated/createAnimatedComponent.js @@ -174,14 +174,11 @@ function createAnimatedComponent( _attachProps(nextProps) { const oldPropsAnimated = this._propsAnimated; - if (nextProps === oldPropsAnimated) { - return; - } - this._propsAnimated = new AnimatedProps( nextProps, this._animatedPropsCallback, ); + this._propsAnimated.__attach(); // When you call detach, it removes the element from the parent list // of children. If it goes to 0, then the parent also detaches itself @@ -202,19 +199,6 @@ function createAnimatedComponent( setLocalRef: ref => { this._prevComponent = this._component; this._component = ref; - - // TODO: Delete this in a future release. - if (ref != null && ref.getNode == null) { - ref.getNode = () => { - console.warn( - '%s: Calling `getNode()` on the ref of an Animated component ' + - 'is no longer necessary. You can now directly use the ref ' + - 'instead. This method will be removed in a future release.', - ref.constructor.name ?? '<>', - ); - return ref; - }; - } }, }); diff --git a/Libraries/Animated/nodes/AnimatedProps.js b/Libraries/Animated/nodes/AnimatedProps.js index 578ed6718d213f..6f915bb5b8fd1d 100644 --- a/Libraries/Animated/nodes/AnimatedProps.js +++ b/Libraries/Animated/nodes/AnimatedProps.js @@ -33,7 +33,6 @@ class AnimatedProps extends AnimatedNode { } this._props = props; this._callback = callback; - this.__attach(); } __getValue(): Object { diff --git a/Libraries/Animated/nodes/AnimatedValue.js b/Libraries/Animated/nodes/AnimatedValue.js index e1d1963e0cb38d..ac3d72915b4116 100644 --- a/Libraries/Animated/nodes/AnimatedValue.js +++ b/Libraries/Animated/nodes/AnimatedValue.js @@ -60,6 +60,17 @@ function _flush(rootNode: AnimatedValue): void { animatedStyles.forEach(animatedStyle => animatedStyle.update()); } +/** + * Some operations are executed only on batch end, which is _mostly_ scheduled when + * Animated component props change. For some of the changes which require immediate execution + * (e.g. setValue), we create a separate batch in case none is scheduled. + */ +function _executeAsAnimatedBatch(id: string, operation: () => void) { + NativeAnimatedAPI.setWaitingForIdentifier(id); + operation(); + NativeAnimatedAPI.unsetWaitingForIdentifier(id); +} + /** * Standard value for driving animations. One `Animated.Value` can drive * multiple properties in a synchronized fashion, but can only be driven by one @@ -115,7 +126,9 @@ class AnimatedValue extends AnimatedWithChildren { !this.__isNative /* don't perform a flush for natively driven values */, ); if (this.__isNative) { - NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value); + _executeAsAnimatedBatch(this.__getNativeTag().toString(), () => { + NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value); + }); } } @@ -183,6 +196,12 @@ class AnimatedValue extends AnimatedWithChildren { resetAnimation(callback?: ?(value: number) => void): void { this.stopAnimation(callback); this._value = this._startingValue; + if (this.__isNative) { + NativeAnimatedAPI.setAnimatedNodeValue( + this.__getNativeTag(), + this._startingValue, + ); + } } _onAnimatedValueUpdateReceived(value: number): void { diff --git a/Libraries/BUCK b/Libraries/BUCK index 389a6e37799081..a2f403115fbc2e 100644 --- a/Libraries/BUCK +++ b/Libraries/BUCK @@ -12,6 +12,7 @@ rn_codegen( name = "FBReactNativeSpec", android_package_name = "com.facebook.fbreact.specs", codegen_modules = True, + ios_assume_nonnull = False, library_labels = ["supermodule:xplat/default/public.react_native.infra"], native_module_spec_name = "FBReactNativeSpec", ) @@ -20,5 +21,6 @@ rn_codegen( rn_codegen( name = "FBReactNativeComponentSpec", codegen_components = True, + ios_assume_nonnull = False, library_labels = ["supermodule:xplat/default/public.react_native.infra"], ) diff --git a/Libraries/BatchedBridge/NativeModules.js b/Libraries/BatchedBridge/NativeModules.js index 4f764463738d9f..a9b7619944e3fc 100644 --- a/Libraries/BatchedBridge/NativeModules.js +++ b/Libraries/BatchedBridge/NativeModules.js @@ -14,7 +14,7 @@ const BatchedBridge = require('./BatchedBridge'); const invariant = require('invariant'); -import type {ExtendedError} from '../Core/Devtools/parseErrorStack'; +import type {ExtendedError} from '../Core/ExtendedError'; export type ModuleConfig = [ string /* name */, diff --git a/Libraries/Blob/RCTBlobManager.h b/Libraries/Blob/RCTBlobManager.h index 96c8f0722f02c9..04b905ccb92a24 100755 --- a/Libraries/Blob/RCTBlobManager.h +++ b/Libraries/Blob/RCTBlobManager.h @@ -8,8 +8,9 @@ #import #import #import +#import -@interface RCTBlobManager : NSObject +@interface RCTBlobManager : NSObject - (NSString *)store:(NSData *)data; diff --git a/Libraries/Blob/RCTBlobManager.mm b/Libraries/Blob/RCTBlobManager.mm index 551c910584fad4..425dc73fb6c077 100755 --- a/Libraries/Blob/RCTBlobManager.mm +++ b/Libraries/Blob/RCTBlobManager.mm @@ -40,10 +40,8 @@ @implementation RCTBlobManager @synthesize moduleRegistry = _moduleRegistry; @synthesize methodQueue = _methodQueue; -- (void)setBridge:(RCTBridge *)bridge +- (void)initialize { - _bridge = bridge; - std::lock_guard lock(_blobsMutex); _blobs = [NSMutableDictionary new]; diff --git a/Libraries/Blob/RCTBlobPlugins.mm b/Libraries/Blob/RCTBlobPlugins.mm index d06f40e5d21120..289094f35d43a0 100644 --- a/Libraries/Blob/RCTBlobPlugins.mm +++ b/Libraries/Blob/RCTBlobPlugins.mm @@ -17,13 +17,14 @@ #import Class RCTBlobClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"FileReaderModule", RCTFileReaderModuleCls}, {"BlobModule", RCTBlobManagerCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/Libraries/Blob/React-RCTBlob.podspec b/Libraries/Blob/React-RCTBlob.podspec index c3f1fb27545d9a..ad8de5c22d5849 100644 --- a/Libraries/Blob/React-RCTBlob.podspec +++ b/Libraries/Blob/React-RCTBlob.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTBlob" diff --git a/Libraries/Blob/URL.js b/Libraries/Blob/URL.js index 0b0e9be74d191d..e839f39ff0d577 100644 --- a/Libraries/Blob/URL.js +++ b/Libraries/Blob/URL.js @@ -105,7 +105,7 @@ export class URLSearchParams { function validateBaseUrl(url: string) { // from this MIT-licensed gist: https://gist.github.com/dperini/729294 - return /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( + return /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)*(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/.test( url, ); } diff --git a/Libraries/Components/ActivityIndicator/ActivityIndicator.js b/Libraries/Components/ActivityIndicator/ActivityIndicator.js index 6202d610d95e22..9100cf6483de2a 100644 --- a/Libraries/Components/ActivityIndicator/ActivityIndicator.js +++ b/Libraries/Components/ActivityIndicator/ActivityIndicator.js @@ -10,14 +10,12 @@ */ 'use strict'; - -const Platform = require('../../Utilities/Platform'); -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); -const View = require('../View/View'); +import * as React from 'react'; +import Platform from '../../Utilities/Platform'; +import StyleSheet, {type ColorValue} from '../../StyleSheet/StyleSheet'; +import View from '../View/View'; import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import type {ViewProps} from '../View/ViewPropTypes'; -import type {ColorValue} from '../../StyleSheet/StyleSheet'; const PlatformActivityIndicator = Platform.OS === 'android' diff --git a/Libraries/Components/Button.js b/Libraries/Components/Button.js index a235b375d02a06..d598a499f25325 100644 --- a/Libraries/Components/Button.js +++ b/Libraries/Components/Button.js @@ -11,18 +11,21 @@ 'use strict'; -const Platform = require('../Utilities/Platform'); -const React = require('react'); -const StyleSheet = require('../StyleSheet/StyleSheet'); -const Text = require('../Text/Text'); -const TouchableNativeFeedback = require('./Touchable/TouchableNativeFeedback'); -const TouchableOpacity = require('./Touchable/TouchableOpacity'); -const View = require('./View/View'); -const invariant = require('invariant'); - -import type {AccessibilityState} from './View/ViewAccessibility'; +import * as React from 'react'; +import Platform from '../Utilities/Platform'; +import StyleSheet, {type ColorValue} from '../StyleSheet/StyleSheet'; +import Text from '../Text/Text'; +import TouchableNativeFeedback from './Touchable/TouchableNativeFeedback'; +import TouchableOpacity from './Touchable/TouchableOpacity'; +import View from './View/View'; +import invariant from 'invariant'; + +import type { + AccessibilityState, + AccessibilityActionEvent, + AccessibilityActionInfo, +} from './View/ViewAccessibility'; import type {PressEvent} from '../Types/CoreEventTypes'; -import type {ColorValue} from '../StyleSheet/StyleSheet'; type ButtonProps = $ReadOnly<{| /** @@ -138,6 +141,9 @@ type ButtonProps = $ReadOnly<{| /** * Accessibility props. */ + accessible?: ?boolean, + accessibilityActions?: ?$ReadOnlyArray, + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, accessibilityState?: ?AccessibilityState, |}>; @@ -267,6 +273,9 @@ class Button extends React.Component { nextFocusRight, nextFocusUp, testID, + accessible, + accessibilityActions, + onAccessibilityAction, } = this.props; const buttonStyles = [styles.button]; const textStyles = [styles.text]; @@ -304,6 +313,9 @@ class Button extends React.Component { return ( ; /** @@ -147,7 +153,7 @@ class DatePickerIOS extends React.Component { ref={picker => { this._picker = picker; }} - style={styles.datePickerIOS} + style={getHeight(props.pickerStyle, props.mode)} date={ props.date ? props.date.getTime() @@ -172,16 +178,51 @@ class DatePickerIOS extends React.Component { onChange={this._onChange} onStartShouldSetResponder={() => true} onResponderTerminationRequest={() => false} + pickerStyle={props.pickerStyle} /> ); } } +const inlineHeightForDatePicker = 318.5; +const inlineHeightForTimePicker = 49.5; +const compactHeight = 40; +const spinnerHeight = 216; + const styles = StyleSheet.create({ datePickerIOS: { - height: 216, + height: spinnerHeight, + }, + datePickerIOSCompact: { + height: compactHeight, + }, + datePickerIOSInline: { + height: inlineHeightForDatePicker + inlineHeightForTimePicker * 2, + }, + datePickerIOSInlineDate: { + height: inlineHeightForDatePicker + inlineHeightForTimePicker, + }, + datePickerIOSInlineTime: { + height: inlineHeightForTimePicker, }, }); +function getHeight(pickerStyle, mode) { + if (pickerStyle === 'compact') { + return styles.datePickerIOSCompact; + } + if (pickerStyle === 'inline') { + switch (mode) { + case 'date': + return styles.datePickerIOSInlineDate; + case 'time': + return styles.datePickerIOSInlineTime; + default: + return styles.datePickerIOSInline; + } + } + return styles.datePickerIOS; +} + module.exports = DatePickerIOS; diff --git a/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js b/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js index b1f9f5ca13a401..e577f3ee37b4d9 100644 --- a/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js +++ b/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js @@ -37,6 +37,7 @@ type NativeProps = $ReadOnly<{| mode?: WithDefault<'date' | 'time' | 'datetime', 'date'>, onChange?: ?BubblingEventHandler, timeZoneOffsetInMinutes?: ?Float, + pickerStyle?: WithDefault<'compact' | 'spinner' | 'inline', 'spinner'>, |}>; type ComponentType = HostComponent; diff --git a/Libraries/Components/Keyboard/Keyboard.js b/Libraries/Components/Keyboard/Keyboard.js index 6227b975adf12c..fec163cd2845cd 100644 --- a/Libraries/Components/Keyboard/Keyboard.js +++ b/Libraries/Components/Keyboard/Keyboard.js @@ -13,7 +13,7 @@ import LayoutAnimation from '../../LayoutAnimation/LayoutAnimation'; import dismissKeyboard from '../../Utilities/dismissKeyboard'; import Platform from '../../Utilities/Platform'; import NativeKeyboardObserver from './NativeKeyboardObserver'; -import {type EventSubscription} from '../../vendor/emitter/EventEmitter'; +import type {EventSubscription} from '../../vendor/emitter/EventEmitter'; export type KeyboardEventName = $Keys; diff --git a/Libraries/Components/MaskedView/MaskedViewIOS.ios.js b/Libraries/Components/MaskedView/MaskedViewIOS.ios.js index 4a32d29836f8d0..eb69fc4233affc 100644 --- a/Libraries/Components/MaskedView/MaskedViewIOS.ios.js +++ b/Libraries/Components/MaskedView/MaskedViewIOS.ios.js @@ -8,9 +8,9 @@ * @flow */ -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); -const View = require('../View/View'); +import * as React from 'react'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import View from '../View/View'; import type {ViewProps} from '../View/ViewPropTypes'; import RCTMaskedViewNativeComponent from './RCTMaskedViewNativeComponent'; diff --git a/Libraries/Components/Picker/Picker.js b/Libraries/Components/Picker/Picker.js index 7a733f32637bcf..bb5416b45e6b2b 100644 --- a/Libraries/Components/Picker/Picker.js +++ b/Libraries/Components/Picker/Picker.js @@ -10,14 +10,18 @@ 'use strict'; -const PickerAndroid = require('./PickerAndroid'); -const PickerIOS = require('./PickerIOS'); -const Platform = require('../../Utilities/Platform'); -const React = require('react'); -const UnimplementedView = require('../UnimplementedViews/UnimplementedView'); +import * as React from 'react'; +import PickerAndroid from './PickerAndroid'; +import PickerIOS from './PickerIOS'; +import Platform from '../../Utilities/Platform'; +import UnimplementedView from '../UnimplementedViews/UnimplementedView'; -import type {TextStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ColorValue} from '../../StyleSheet/StyleSheet'; +import type {TextStyleProp, ColorValue} from '../../StyleSheet/StyleSheet'; + +import type { + AccessibilityActionEvent, + AccessibilityActionInfo, +} from '../View/ViewAccessibility'; const MODE_DIALOG = 'dialog'; const MODE_DROPDOWN = 'dropdown'; @@ -116,6 +120,27 @@ type PickerProps = $ReadOnly<{| * The string used for the accessibility label. Will be read once focused on the picker but not on change. */ accessibilityLabel?: ?string, + + /** + * When `true`, indicates that the view is an accessibility element. + * By default, all the touchable elements are accessible. + * + * See https://reactnative.dev/docs/view.html#accessible + */ + accessible?: ?boolean, + + /** + * Provides an array of custom actions available for accessibility. + * + */ + accessibilityActions?: ?$ReadOnlyArray, + + /** + * When `accessible` is true, the system will try to invoke this function + * when the user performs an accessibility custom action. + * + */ + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, |}>; /** diff --git a/Libraries/Components/Picker/PickerAndroid.android.js b/Libraries/Components/Picker/PickerAndroid.android.js index 3f19114690a0ac..fdf6a420ca5345 100644 --- a/Libraries/Components/Picker/PickerAndroid.android.js +++ b/Libraries/Components/Picker/PickerAndroid.android.js @@ -19,6 +19,11 @@ import StyleSheet from '../../StyleSheet/StyleSheet'; import invariant from 'invariant'; import processColor from '../../StyleSheet/processColor'; +import type { + AccessibilityActionEvent, + AccessibilityActionInfo, +} from '../View/ViewAccessibility'; + import type {SyntheticEvent} from '../../Types/CoreEventTypes'; import type {ColorValue, TextStyleProp} from '../../StyleSheet/StyleSheet'; @@ -31,6 +36,9 @@ type PickerItemSelectSyntheticEvent = SyntheticEvent< type PickerItemValue = number | string; type Props = $ReadOnly<{| + accessible?: ?boolean, + accessibilityActions?: ?$ReadOnlyArray, + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, accessibilityLabel?: ?Stringish, children?: React.Node, style?: ?TextStyleProp, @@ -111,6 +119,9 @@ function PickerAndroid(props: Props): React.Node { ); const rootProps = { + accessible: props.accessible, + accessibilityActions: props.accessibilityActions, + onAccessibilityAction: props.onAccessibilityAction, accessibilityLabel: props.accessibilityLabel, enabled: props.enabled, items, diff --git a/Libraries/Components/Picker/PickerIOS.ios.js b/Libraries/Components/Picker/PickerIOS.ios.js index fcdecf2f5934d5..93c1c4821cfab2 100644 --- a/Libraries/Components/Picker/PickerIOS.ios.js +++ b/Libraries/Components/Picker/PickerIOS.ios.js @@ -10,19 +10,20 @@ // This is a controlled component version of RCTPickerIOS. -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); -const View = require('../View/View'); - -const invariant = require('invariant'); -const processColor = require('../../StyleSheet/processColor'); +import * as React from 'react'; +import StyleSheet, { + type TextStyleProp, + type ColorValue, +} from '../../StyleSheet/StyleSheet'; +import View from '../View/View'; +import invariant from 'invariant'; +import processColor, { + type ProcessedColorValue, +} from '../../StyleSheet/processColor'; import RCTPickerNativeComponent, { Commands as PickerCommands, } from './RCTPickerNativeComponent'; -import type {TextStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ColorValue} from '../../StyleSheet/StyleSheet'; -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; import type {ViewProps} from '../View/ViewPropTypes'; diff --git a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js index 8396ac4e87981e..d642a6545ab5bb 100644 --- a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js +++ b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js @@ -8,11 +8,10 @@ */ 'use strict'; - -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); -const Text = require('../../Text/Text'); -const View = require('../View/View'); +import * as React from 'react'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import Text from '../../Text/Text'; +import View from '../View/View'; class DummyProgressViewIOS extends React.Component { render() { diff --git a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js index c3f5352e68740d..d465440d174872 100644 --- a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js +++ b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js @@ -8,12 +8,11 @@ * @flow strict-local */ -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); +import * as React from 'react'; +import StyleSheet, {type ColorValue} from '../../StyleSheet/StyleSheet'; import RCTProgressViewNativeComponent from './RCTProgressViewNativeComponent'; import type {ImageSource} from '../../Image/ImageSource'; -import type {ColorValue} from '../../StyleSheet/StyleSheet'; import type {ViewProps} from '../View/ViewPropTypes'; type Props = $ReadOnly<{| diff --git a/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js b/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js index 40d41abbdc68ec..696eaa37ae7d2d 100644 --- a/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +++ b/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js @@ -9,10 +9,9 @@ */ 'use strict'; +import * as React from 'react'; -const React = require('react'); - -const requireNativeComponent = require('../../../ReactNative/requireNativeComponent'); +import requireNativeComponent from '../../../ReactNative/requireNativeComponent'; import type {HostComponent} from '../../../Renderer/shims/ReactNativeTypes'; diff --git a/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js b/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js index 6c68faf202ad50..05f629e01a1d1e 100644 --- a/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +++ b/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js @@ -8,8 +8,8 @@ * @format */ -import {type ScrollViewNativeProps as Props} from './ScrollViewNativeComponentType'; -import {type HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import type {ScrollViewNativeProps as Props} from './ScrollViewNativeComponentType'; +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry'; const AndroidHorizontalScrollViewNativeComponent: HostComponent = NativeComponentRegistry.get( diff --git a/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js b/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js index 702900a3b89cb6..4e3174044dfc8b 100644 --- a/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js +++ b/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js @@ -8,9 +8,9 @@ * @flow */ -import {type HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry'; -import {type ViewProps as Props} from '../View/ViewPropTypes'; +import type {ViewProps as Props} from '../View/ViewPropTypes'; const ScrollContentViewNativeComponent: HostComponent = NativeComponentRegistry.get( 'RCTScrollContentView', diff --git a/Libraries/Components/ScrollView/ScrollViewNativeComponent.js b/Libraries/Components/ScrollView/ScrollViewNativeComponent.js index e74fb870e34c02..f5433a0b25e21c 100644 --- a/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +++ b/Libraries/Components/ScrollView/ScrollViewNativeComponent.js @@ -8,8 +8,8 @@ * @format */ -import {type ScrollViewNativeProps as Props} from './ScrollViewNativeComponentType'; -import {type HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import type {ScrollViewNativeProps as Props} from './ScrollViewNativeComponentType'; +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry'; const ScrollViewNativeComponent: HostComponent = NativeComponentRegistry.get( diff --git a/Libraries/Components/ScrollView/ScrollViewStickyHeader.js b/Libraries/Components/ScrollView/ScrollViewStickyHeader.js index a17d6350c65abc..f530be611602e1 100644 --- a/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +++ b/Libraries/Components/ScrollView/ScrollViewStickyHeader.js @@ -4,31 +4,25 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict-local * @format */ -import AnimatedImplementation from '../../Animated/AnimatedImplementation'; -import AnimatedAddition from '../../Animated/nodes/AnimatedAddition'; -import AnimatedDiffClamp from '../../Animated/nodes/AnimatedDiffClamp'; -import AnimatedNode from '../../Animated/nodes/AnimatedNode'; - -import * as React from 'react'; -import StyleSheet from '../../StyleSheet/StyleSheet'; -import View from '../View/View'; -import Platform from '../../Utilities/Platform'; - import type {LayoutEvent} from '../../Types/CoreEventTypes'; +import setAndForwardRef from 'react-native/Libraries/Utilities/setAndForwardRef'; +import Platform from '../../Utilities/Platform'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import Animated from '../../Animated/Animated'; +import * as React from 'react'; +import {useEffect, useMemo, useRef, useCallback} from 'react'; -import ScrollViewStickyHeaderInjection from './ScrollViewStickyHeaderInjection'; - -const AnimatedView = AnimatedImplementation.createAnimatedComponent(View); +const AnimatedView = Animated.View; export type Props = $ReadOnly<{ - children?: React.Element, + children?: React.Element<$FlowFixMe>, nextHeaderLayoutY: ?number, onLayout: (event: LayoutEvent) => void, - scrollAnimatedValue: AnimatedImplementation.Value, + scrollAnimatedValue: Animated.Value, // Will cause sticky headers to stick at the bottom of the ScrollView instead // of the top. inverted: ?boolean, @@ -38,287 +32,275 @@ export type Props = $ReadOnly<{ hiddenOnScroll?: ?boolean, }>; -type State = { - measured: boolean, - layoutY: number, - layoutHeight: number, - nextHeaderLayoutY: ?number, - translateY: ?number, - ... -}; +const ScrollViewStickyHeaderWithForwardedRef: React.AbstractComponent< + Props, + $ReadOnly<{ + setNextHeaderY: number => void, + ...$Exact>, + }>, +> = React.forwardRef(function ScrollViewStickyHeader(props, forwardedRef) { + const { + inverted, + scrollViewHeight, + hiddenOnScroll, + scrollAnimatedValue, + nextHeaderLayoutY: _nextHeaderLayoutY, + } = props; -class ScrollViewStickyHeader extends React.Component { - state: State = { - measured: false, - layoutY: 0, - layoutHeight: 0, - nextHeaderLayoutY: this.props.nextHeaderLayoutY, - translateY: null, - }; + const [measured, setMeasured] = React.useState(false); + const [layoutY, setLayoutY] = React.useState(0); + const [layoutHeight, setLayoutHeight] = React.useState(0); + const [translateY, setTranslateY] = React.useState(null); + const [nextHeaderLayoutY, setNextHeaderLayoutY] = React.useState( + _nextHeaderLayoutY, + ); + const [isFabric, setIsFabric] = React.useState(false); - _translateY: ?AnimatedNode = null; - _shouldRecreateTranslateY: boolean = true; - _haveReceivedInitialZeroTranslateY: boolean = true; - _ref: any; // TODO T53738161: flow type this, and the whole file + const componentRef = React.useRef>(); + const _setNativeRef = setAndForwardRef({ + getForwardedRef: () => forwardedRef, + setLocalRef: ref => { + componentRef.current = ref; + if (ref) { + ref.setNextHeaderY = value => { + setNextHeaderLayoutY(value); + }; + setIsFabric( + !!( + // An internal transform mangles variables with leading "_" as private. + // eslint-disable-next-line dot-notation + ref['_internalInstanceHandle']?.stateNode?.canonical + ), + ); + } + }, + }); - // Fabric-only: - _timer: ?TimeoutID; - _animatedValueListenerId: string; - _animatedValueListener: (valueObject: $ReadOnly<{|value: number|}>) => void; - _debounceTimeout: number = Platform.OS === 'android' ? 15 : 64; + const offset = useMemo( + () => + hiddenOnScroll === true + ? Animated.diffClamp( + scrollAnimatedValue + .interpolate({ + extrapolateLeft: 'clamp', + inputRange: [layoutY, layoutY + 1], + outputRange: ([0, 1]: Array), + }) + .interpolate({ + inputRange: [0, 1], + outputRange: ([0, -1]: Array), + }), + -layoutHeight, + 0, + ) + : null, + [scrollAnimatedValue, layoutHeight, layoutY, hiddenOnScroll], + ); - setNextHeaderY(y: number) { - this._shouldRecreateTranslateY = true; - this.setState({nextHeaderLayoutY: y}); - } + const [ + animatedTranslateY, + setAnimatedTranslateY, + ] = React.useState(() => { + const inputRange: Array = [-1, 0]; + const outputRange: Array = [0, 0]; + const initialTranslateY: Animated.Interpolation = scrollAnimatedValue.interpolate( + { + inputRange, + outputRange, + }, + ); - componentWillUnmount() { - if (this._translateY != null && this._animatedValueListenerId != null) { - this._translateY.removeListener(this._animatedValueListenerId); + if (offset != null) { + return Animated.add(initialTranslateY, offset); } - if (this._timer) { - clearTimeout(this._timer); - } - } + return initialTranslateY; + }); - UNSAFE_componentWillReceiveProps(nextProps: Props) { - if ( - nextProps.scrollViewHeight !== this.props.scrollViewHeight || - nextProps.scrollAnimatedValue !== this.props.scrollAnimatedValue || - nextProps.inverted !== this.props.inverted - ) { - this._shouldRecreateTranslateY = true; - } - } + const _haveReceivedInitialZeroTranslateY = useRef(true); + const _timer = useRef(null); - updateTranslateListener( - translateY: AnimatedImplementation.Interpolation, - isFabric: boolean, - offset: AnimatedDiffClamp | null, - ) { - if (this._translateY != null && this._animatedValueListenerId != null) { - this._translateY.removeListener(this._animatedValueListenerId); + useEffect(() => { + if (translateY !== 0 && translateY != null) { + _haveReceivedInitialZeroTranslateY.current = false; } - offset - ? (this._translateY = new AnimatedAddition(translateY, offset)) - : (this._translateY = translateY); + }, [translateY]); - this._shouldRecreateTranslateY = false; + // This is called whenever the (Interpolated) Animated Value + // updates, which is several times per frame during scrolling. + // To ensure that the Fabric ShadowTree has the most recent + // translate style of this node, we debounce the value and then + // pass it through to the underlying node during render. + // This is: + // 1. Only an issue in Fabric. + // 2. Worse in Android than iOS. In Android, but not iOS, you + // can touch and move your finger slightly and still trigger + // a "tap" event. In iOS, moving will cancel the tap in + // both Fabric and non-Fabric. On Android when you move + // your finger, the hit-detection moves from the Android + // platform to JS, so we need the ShadowTree to have knowledge + // of the current position. + const animatedValueListener = useCallback( + ({value}) => { + const _debounceTimeout: number = Platform.OS === 'android' ? 15 : 64; + // When the AnimatedInterpolation is recreated, it always initializes + // to a value of zero and emits a value change of 0 to its listeners. + if (value === 0 && !_haveReceivedInitialZeroTranslateY.current) { + _haveReceivedInitialZeroTranslateY.current = true; + return; + } + if (_timer.current != null) { + clearTimeout(_timer.current); + } + _timer.current = setTimeout(() => { + if (value !== translateY) { + setTranslateY(value); + } + }, _debounceTimeout); + }, + [translateY], + ); - if (!isFabric) { - return; - } + useEffect(() => { + const inputRange: Array = [-1, 0]; + const outputRange: Array = [0, 0]; - if (!this._animatedValueListener) { - // This is called whenever the (Interpolated) Animated Value - // updates, which is several times per frame during scrolling. - // To ensure that the Fabric ShadowTree has the most recent - // translate style of this node, we debounce the value and then - // pass it through to the underlying node during render. - // This is: - // 1. Only an issue in Fabric. - // 2. Worse in Android than iOS. In Android, but not iOS, you - // can touch and move your finger slightly and still trigger - // a "tap" event. In iOS, moving will cancel the tap in - // both Fabric and non-Fabric. On Android when you move - // your finger, the hit-detection moves from the Android - // platform to JS, so we need the ShadowTree to have knowledge - // of the current position. - this._animatedValueListener = ({value}) => { - // When the AnimatedInterpolation is recreated, it always initializes - // to a value of zero and emits a value change of 0 to its listeners. - if (value === 0 && !this._haveReceivedInitialZeroTranslateY) { - this._haveReceivedInitialZeroTranslateY = true; - return; + if (measured) { + if (inverted === true) { + // The interpolation looks like: + // - Negative scroll: no translation + // - `stickStartPoint` is the point at which the header will start sticking. + // It is calculated using the ScrollView viewport height so it is a the bottom. + // - Headers that are in the initial viewport will never stick, `stickStartPoint` + // will be negative. + // - From 0 to `stickStartPoint` no translation. This will cause the header + // to scroll normally until it reaches the top of the scroll view. + // - From `stickStartPoint` to when the next header y hits the bottom edge of the header: translate + // equally to scroll. This will cause the header to stay at the top of the scroll view. + // - Past the collision with the next header y: no more translation. This will cause the + // header to continue scrolling up and make room for the next sticky header. + // In the case that there is no next header just translate equally to + // scroll indefinitely. + if (scrollViewHeight != null) { + const stickStartPoint = layoutY + layoutHeight - scrollViewHeight; + if (stickStartPoint > 0) { + inputRange.push(stickStartPoint); + outputRange.push(0); + inputRange.push(stickStartPoint + 1); + outputRange.push(1); + // If the next sticky header has not loaded yet (probably windowing) or is the last + // we can just keep it sticked forever. + const collisionPoint = + (nextHeaderLayoutY || 0) - layoutHeight - scrollViewHeight; + if (collisionPoint > stickStartPoint) { + inputRange.push(collisionPoint, collisionPoint + 1); + outputRange.push( + collisionPoint - stickStartPoint, + collisionPoint - stickStartPoint, + ); + } + } } - if (this._timer) { - clearTimeout(this._timer); + } else { + // The interpolation looks like: + // - Negative scroll: no translation + // - From 0 to the y of the header: no translation. This will cause the header + // to scroll normally until it reaches the top of the scroll view. + // - From header y to when the next header y hits the bottom edge of the header: translate + // equally to scroll. This will cause the header to stay at the top of the scroll view. + // - Past the collision with the next header y: no more translation. This will cause the + // header to continue scrolling up and make room for the next sticky header. + // In the case that there is no next header just translate equally to + // scroll indefinitely. + inputRange.push(layoutY); + outputRange.push(0); + // If the next sticky header has not loaded yet (probably windowing) or is the last + // we can just keep it sticked forever. + const collisionPoint = (nextHeaderLayoutY || 0) - layoutHeight; + if (collisionPoint >= layoutY) { + inputRange.push(collisionPoint, collisionPoint + 1); + outputRange.push(collisionPoint - layoutY, collisionPoint - layoutY); + } else { + inputRange.push(layoutY + 1); + outputRange.push(1); } - this._timer = setTimeout(() => { - if (value !== this.state.translateY) { - this.setState({ - translateY: value, - }); - } - }, this._debounceTimeout); - }; - } - if (this.state.translateY !== 0 && this.state.translateY != null) { - this._haveReceivedInitialZeroTranslateY = false; - } - this._animatedValueListenerId = translateY.addListener( - this._animatedValueListener, - ); - } - - _onLayout = event => { - const layoutY = event.nativeEvent.layout.y; - const layoutHeight = event.nativeEvent.layout.height; - const measured = true; - - if ( - layoutY !== this.state.layoutY || - layoutHeight !== this.state.layoutHeight || - measured !== this.state.measured - ) { - this._shouldRecreateTranslateY = true; + } } - this.setState({ - measured, - layoutY, - layoutHeight, + let newAnimatedTranslateY: Animated.Node = scrollAnimatedValue.interpolate({ + inputRange, + outputRange, }); - this.props.onLayout(event); - const child = React.Children.only(this.props.children); - if (child.props.onLayout) { - child.props.onLayout(event); + if (offset != null) { + newAnimatedTranslateY = Animated.add(newAnimatedTranslateY, offset); } - }; - _setComponentRef = ref => { - this._ref = ref; - }; + // add the event listener + let animatedListenerId; + if (isFabric) { + animatedListenerId = newAnimatedTranslateY.addListener( + animatedValueListener, + ); + } - render(): React.Node { - // Fabric Detection - const isFabric = !!( - // An internal transform mangles variables with leading "_" as private. - // eslint-disable-next-line dot-notation - (this._ref && this._ref['_internalInstanceHandle']?.stateNode?.canonical) - ); - // Initially and in the case of updated props or layout, we - // recreate this interpolated value. Otherwise, we do not recreate - // when there are state changes. - if (this._shouldRecreateTranslateY) { - const {inverted, scrollViewHeight} = this.props; - const {measured, layoutHeight, layoutY, nextHeaderLayoutY} = this.state; - const inputRange: Array = [-1, 0]; - const outputRange: Array = [0, 0]; + setAnimatedTranslateY(newAnimatedTranslateY); - if (measured) { - if (inverted) { - // The interpolation looks like: - // - Negative scroll: no translation - // - `stickStartPoint` is the point at which the header will start sticking. - // It is calculated using the ScrollView viewport height so it is a the bottom. - // - Headers that are in the initial viewport will never stick, `stickStartPoint` - // will be negative. - // - From 0 to `stickStartPoint` no translation. This will cause the header - // to scroll normally until it reaches the top of the scroll view. - // - From `stickStartPoint` to when the next header y hits the bottom edge of the header: translate - // equally to scroll. This will cause the header to stay at the top of the scroll view. - // - Past the collision with the next header y: no more translation. This will cause the - // header to continue scrolling up and make room for the next sticky header. - // In the case that there is no next header just translate equally to - // scroll indefinitely. - if (scrollViewHeight != null) { - const stickStartPoint = layoutY + layoutHeight - scrollViewHeight; - if (stickStartPoint > 0) { - inputRange.push(stickStartPoint); - outputRange.push(0); - inputRange.push(stickStartPoint + 1); - outputRange.push(1); - // If the next sticky header has not loaded yet (probably windowing) or is the last - // we can just keep it sticked forever. - const collisionPoint = - (nextHeaderLayoutY || 0) - layoutHeight - scrollViewHeight; - if (collisionPoint > stickStartPoint) { - inputRange.push(collisionPoint, collisionPoint + 1); - outputRange.push( - collisionPoint - stickStartPoint, - collisionPoint - stickStartPoint, - ); - } - } - } - } else { - // The interpolation looks like: - // - Negative scroll: no translation - // - From 0 to the y of the header: no translation. This will cause the header - // to scroll normally until it reaches the top of the scroll view. - // - From header y to when the next header y hits the bottom edge of the header: translate - // equally to scroll. This will cause the header to stay at the top of the scroll view. - // - Past the collision with the next header y: no more translation. This will cause the - // header to continue scrolling up and make room for the next sticky header. - // In the case that there is no next header just translate equally to - // scroll indefinitely. - inputRange.push(layoutY); - outputRange.push(0); - // If the next sticky header has not loaded yet (probably windowing) or is the last - // we can just keep it sticked forever. - const collisionPoint = (nextHeaderLayoutY || 0) - layoutHeight; - if (collisionPoint >= layoutY) { - inputRange.push(collisionPoint, collisionPoint + 1); - outputRange.push( - collisionPoint - layoutY, - collisionPoint - layoutY, - ); - } else { - inputRange.push(layoutY + 1); - outputRange.push(1); - } - } + // clean up the event listener and timer + return () => { + if (animatedListenerId) { + newAnimatedTranslateY.removeListener(animatedListenerId); } + if (_timer.current != null) { + clearTimeout(_timer.current); + } + }; + }, [nextHeaderLayoutY, measured, layoutHeight, layoutY, scrollViewHeight, scrollAnimatedValue, inverted, offset, animatedValueListener, isFabric]); - this.updateTranslateListener( - this.props.scrollAnimatedValue.interpolate({ - inputRange, - outputRange, - }), - isFabric, - this.props.hiddenOnScroll - ? new AnimatedDiffClamp( - this.props.scrollAnimatedValue - .interpolate({ - extrapolateLeft: 'clamp', - inputRange: [layoutY, layoutY + 1], - outputRange: ([0, 1]: Array), - }) - .interpolate({ - inputRange: [0, 1], - outputRange: ([0, -1]: Array), - }), - -this.state.layoutHeight, - 0, - ) - : null, - ); + const _onLayout = (event: LayoutEvent) => { + setLayoutY(event.nativeEvent.layout.y); + setLayoutHeight(event.nativeEvent.layout.height); + setMeasured(true); + + props.onLayout(event); + const child = React.Children.only(props.children); + if (child.props.onLayout) { + child.props.onLayout(event); } + }; - const child = React.Children.only(this.props.children); + const child = React.Children.only(props.children); - // TODO T68319535: remove this if NativeAnimated is rewritten for Fabric - const passthroughAnimatedPropExplicitValues = - isFabric && this.state.translateY != null - ? { - style: {transform: [{translateY: this.state.translateY}]}, - } - : null; + // TODO T68319535: remove this if NativeAnimated is rewritten for Fabric + const passthroughAnimatedPropExplicitValues = + isFabric && translateY != null + ? { + style: {transform: [{translateY: translateY}]}, + } + : null; - return ( - - {React.cloneElement(child, { - style: styles.fill, // We transfer the child style to the wrapper. - onLayout: undefined, // we call this manually through our this._onLayout - })} - - ); - } -} + return ( + /* $FlowFixMe[prop-missing] passthroughAnimatedPropExplicitValues isn't properly + included in the Animated.View flow type. */ + + {React.cloneElement(child, { + style: styles.fill, // We transfer the child style to the wrapper. + onLayout: undefined, // we call this manually through our this._onLayout + })} + + ); +}); const styles = StyleSheet.create({ header: { @@ -330,8 +312,4 @@ const styles = StyleSheet.create({ }, }); -const SHToExport: React.AbstractComponent< - Props, - $ReadOnly<{setNextHeaderY: number => void, ...}>, -> = ScrollViewStickyHeaderInjection.unstable_SH ?? ScrollViewStickyHeader; -module.exports = SHToExport; +export default ScrollViewStickyHeaderWithForwardedRef; diff --git a/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js b/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js index a5f56f2f7a7cab..a4cbc5e98425b2 100644 --- a/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js +++ b/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js @@ -8,11 +8,10 @@ */ 'use strict'; - -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); -const Text = require('../../Text/Text'); -const View = require('../View/View'); +import * as React from 'react'; +import StyleSheet from '../../StyleSheet/StyleSheet'; +import Text from '../../Text/Text'; +import View from '../View/View'; class DummySegmentedControlIOS extends React.Component { render() { diff --git a/Libraries/Components/Slider/Slider.js b/Libraries/Components/Slider/Slider.js index 90bbfbf6fee91e..c4cf2074b23807 100644 --- a/Libraries/Components/Slider/Slider.js +++ b/Libraries/Components/Slider/Slider.js @@ -8,16 +8,18 @@ * @flow strict-local */ -const Platform = require('../../Utilities/Platform'); +import * as React from 'react'; +import Platform from '../../Utilities/Platform'; import SliderNativeComponent from './SliderNativeComponent'; -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); +import StyleSheet, { + type ViewStyleProp, + type ColorValue, +} from '../../StyleSheet/StyleSheet'; import type {ImageSource} from '../../Image/ImageSource'; -import type {ViewStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ColorValue} from '../../StyleSheet/StyleSheet'; import type {ViewProps} from '../View/ViewPropTypes'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; +import type {AccessibilityState} from '../View/ViewAccessibility'; type Event = SyntheticEvent< $ReadOnly<{| @@ -130,6 +132,11 @@ type Props = $ReadOnly<{| * Used to locate this view in UI automation tests. */ testID?: ?string, + + /** + Indicates to accessibility services that UI Component is in a specific State. + */ + accessibilityState?: ?AccessibilityState, |}>; /** @@ -199,7 +206,6 @@ const Slider = ( const style = StyleSheet.compose(styles.slider, props.style); const { - disabled = false, value = 0.5, minimumValue = 0, maximumValue = 1, @@ -229,9 +235,16 @@ const Slider = ( } : null; + const disabled = + props.disabled === true || props.accessibilityState?.disabled === true; + const accessibilityState = disabled + ? {...props.accessibilityState, disabled: true} + : props.accessibilityState; + return ( Promise | void, |}>; +const returnsFalse = () => false; +const returnsTrue = () => true; /** Renders a boolean input. @@ -128,132 +129,103 @@ export type Props = $ReadOnly<{| export default App; ``` */ -class Switch extends React.Component { - _nativeSwitchRef: ?React.ElementRef< +export default function Switch(props: Props): React.Node { + const { + disabled, + ios_backgroundColor, + onChange, + onValueChange, + style, + thumbColor, + trackColor, + value, + ...restProps + } = props; + const trackColorForFalse = trackColor?.false; + const trackColorForTrue = trackColor?.true; + + const nativeSwitchRef = React.useRef; - _lastNativeValue: ?boolean; - - render(): React.Node { - const { - disabled, - ios_backgroundColor, - onChange, - onValueChange, - style, - thumbColor, - trackColor, - value, - ...props - } = this.props; + >>(null); + const [native, setNative] = React.useState({value: null}); - const trackColorForFalse = trackColor?.false; - const trackColorForTrue = trackColor?.true; - - if (Platform.OS === 'android') { - const platformProps = { - enabled: disabled !== true, - on: value === true, - style, - thumbTintColor: thumbColor, - trackColorForFalse: trackColorForFalse, - trackColorForTrue: trackColorForTrue, - trackTintColor: value === true ? trackColorForTrue : trackColorForFalse, - }; - - return ( - - ); - } else { - const platformProps = { - disabled, - onTintColor: trackColorForTrue, - style: StyleSheet.compose( - {height: 31, width: 51}, - StyleSheet.compose( - style, - ios_backgroundColor == null - ? null - : { - backgroundColor: ios_backgroundColor, - borderRadius: 16, - }, - ), - ), - thumbTintColor: thumbColor, - tintColor: trackColorForFalse, - value: value === true, - }; - - return ( - - ); - } - } + const handleChange = (event: SwitchChangeEvent) => { + onChange?.(event); + onValueChange?.(event.nativeEvent.value); + setNative({value: event.nativeEvent.value}); + }; - componentDidUpdate() { + React.useLayoutEffect(() => { // This is necessary in case native updates the switch and JS decides // that the update should be ignored and we should stick with the value // that we have in JS. - const value = this.props.value === true; - const nativeValue = this._lastNativeValue !== value ? value : null; - + const jsValue = value === true; + const shouldUpdateNativeSwitch = native.value !== jsValue; if ( - nativeValue != null && - this._nativeSwitchRef && - this._nativeSwitchRef.setNativeProps + shouldUpdateNativeSwitch && + nativeSwitchRef.current?.setNativeProps != null ) { if (Platform.OS === 'android') { - AndroidSwitchCommands.setNativeValue( - this._nativeSwitchRef, - nativeValue, - ); + AndroidSwitchCommands.setNativeValue(nativeSwitchRef.current, jsValue); } else { - SwitchCommands.setValue(this._nativeSwitchRef, nativeValue); + SwitchCommands.setValue(nativeSwitchRef.current, jsValue); } } - } + }, [value, native]); - _handleChange = (event: SwitchChangeEvent) => { - if (this.props.onChange != null) { - this.props.onChange(event); - } - - if (this.props.onValueChange != null) { - this.props.onValueChange(event.nativeEvent.value); - } + if (Platform.OS === 'android') { + const platformProps = { + enabled: disabled !== true, + on: value === true, + style, + thumbTintColor: thumbColor, + trackColorForFalse: trackColorForFalse, + trackColorForTrue: trackColorForTrue, + trackTintColor: value === true ? trackColorForTrue : trackColorForFalse, + }; - this._lastNativeValue = event.nativeEvent.value; - this.forceUpdate(); - }; + return ( + + ); + } else { + const platformProps = { + disabled, + onTintColor: trackColorForTrue, + style: StyleSheet.compose( + {height: 31, width: 51}, + StyleSheet.compose( + style, + ios_backgroundColor == null + ? null + : { + backgroundColor: ios_backgroundColor, + borderRadius: 16, + }, + ), + ), + thumbTintColor: thumbColor, + tintColor: trackColorForFalse, + value: value === true, + }; - _handleSwitchNativeComponentRef = ( - ref: ?React.ElementRef< - typeof SwitchNativeComponent | typeof AndroidSwitchNativeComponent, - >, - ) => { - this._nativeSwitchRef = ref; - }; + return ( + + ); + } } - -const returnsFalse = () => false; -const returnsTrue = () => true; - -module.exports = (SwitchInjection.unstable_Switch ?? - Switch: React.AbstractComponent>); diff --git a/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js b/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js index e96df0585aed1d..b8d559a295418e 100644 --- a/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +++ b/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js @@ -18,8 +18,11 @@ import type { WithDefault, } from '../../Types/CodegenTypes'; import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -import type {TextStyleProp, ViewStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ColorValue} from '../../StyleSheet/StyleSheet'; +import type { + TextStyleProp, + ViewStyleProp, + ColorValue, +} from '../../StyleSheet/StyleSheet'; import requireNativeComponent from '../../ReactNative/requireNativeComponent'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import type {TextInputNativeCommands} from './TextInputNativeCommands'; diff --git a/Libraries/Components/TextInput/AndroidTextInputViewConfig.js b/Libraries/Components/TextInput/AndroidTextInputViewConfig.js index d1f922dccbe4c1..e1a693d5f7053e 100644 --- a/Libraries/Components/TextInput/AndroidTextInputViewConfig.js +++ b/Libraries/Components/TextInput/AndroidTextInputViewConfig.js @@ -9,7 +9,7 @@ */ import ReactNativeViewViewConfig from '../../Components/View/ReactNativeViewViewConfig'; -import {type PartialViewConfig} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes'; +import type {PartialViewConfig} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes'; const AndroidTextInputViewConfig = { uiViewClassName: 'AndroidTextInput', diff --git a/Libraries/Components/TextInput/InputAccessoryView.js b/Libraries/Components/TextInput/InputAccessoryView.js index 0da3ed3d332429..eb83a9ca0e7b8e 100644 --- a/Libraries/Components/TextInput/InputAccessoryView.js +++ b/Libraries/Components/TextInput/InputAccessoryView.js @@ -8,15 +8,15 @@ * @format */ -const Platform = require('../../Utilities/Platform'); -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); +import * as React from 'react'; +import Platform from '../../Utilities/Platform'; +import StyleSheet, { + type ViewStyleProp, + type ColorValue, +} from '../../StyleSheet/StyleSheet'; import RCTInputAccessoryViewNativeComponent from './RCTInputAccessoryViewNativeComponent'; -import type {ViewStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ColorValue} from '../../StyleSheet/StyleSheet'; - /** * Note: iOS only * diff --git a/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js b/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js index bd43ced4b6573a..51e79f707e8d64 100644 --- a/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +++ b/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js @@ -9,11 +9,10 @@ */ import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -import requireNativeComponent from '../../ReactNative/requireNativeComponent'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import type {TextInputNativeCommands} from './TextInputNativeCommands'; import RCTTextInputViewConfig from './RCTTextInputViewConfig'; -const ReactNativeViewConfigRegistry = require('../../Renderer/shims/ReactNativeViewConfigRegistry'); +import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry'; type NativeType = HostComponent; @@ -23,17 +22,10 @@ export const Commands: NativeCommands = codegenNativeCommands({ supportedCommands: ['focus', 'blur', 'setTextAndSelection'], }); -let MultilineTextInputNativeComponent; -if (global.RN$Bridgeless) { - ReactNativeViewConfigRegistry.register('RCTMultilineTextInputView', () => { - return RCTTextInputViewConfig; - }); - MultilineTextInputNativeComponent = 'RCTMultilineTextInputView'; -} else { - MultilineTextInputNativeComponent = requireNativeComponent( - 'RCTMultilineTextInputView', - ); -} +const MultilineTextInputNativeComponent: HostComponent = NativeComponentRegistry.get( + 'RCTMultilineTextInputView', + () => RCTTextInputViewConfig, +); // flowlint-next-line unclear-type:off export default ((MultilineTextInputNativeComponent: any): HostComponent); diff --git a/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js b/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js index d6b14eef521a01..e9ac2bc9cc20ca 100644 --- a/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +++ b/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js @@ -9,11 +9,10 @@ */ import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -import requireNativeComponent from '../../ReactNative/requireNativeComponent'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import type {TextInputNativeCommands} from './TextInputNativeCommands'; import RCTTextInputViewConfig from './RCTTextInputViewConfig'; -const ReactNativeViewConfigRegistry = require('../../Renderer/shims/ReactNativeViewConfigRegistry'); +import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry'; type NativeType = HostComponent; @@ -23,17 +22,10 @@ export const Commands: NativeCommands = codegenNativeCommands({ supportedCommands: ['focus', 'blur', 'setTextAndSelection'], }); -let SinglelineTextInputNativeComponent; -if (global.RN$Bridgeless) { - ReactNativeViewConfigRegistry.register('RCTSinglelineTextInputView', () => { - return RCTTextInputViewConfig; - }); - SinglelineTextInputNativeComponent = 'RCTSinglelineTextInputView'; -} else { - SinglelineTextInputNativeComponent = requireNativeComponent( - 'RCTSinglelineTextInputView', - ); -} +const SinglelineTextInputNativeComponent: HostComponent = NativeComponentRegistry.get( + 'RCTSinglelineTextInputView', + () => RCTTextInputViewConfig, +); // flowlint-next-line unclear-type:off export default ((SinglelineTextInputNativeComponent: any): HostComponent); diff --git a/Libraries/Components/TextInput/RCTTextInputViewConfig.js b/Libraries/Components/TextInput/RCTTextInputViewConfig.js index 54a5de02f928ec..1eb800e69b06e7 100644 --- a/Libraries/Components/TextInput/RCTTextInputViewConfig.js +++ b/Libraries/Components/TextInput/RCTTextInputViewConfig.js @@ -8,8 +8,8 @@ * @format */ +import type {PartialViewConfig} from '../../Renderer/shims/ReactNativeTypes'; import ReactNativeViewViewConfig from '../../Components/View/ReactNativeViewViewConfig'; -import {type ViewConfig} from '../../Renderer/shims/ReactNativeTypes'; const RCTTextInputViewConfig = { uiViewClassName: 'RCTSinglelineTextInputView', @@ -130,4 +130,4 @@ const RCTTextInputViewConfig = { }, }; -module.exports = (RCTTextInputViewConfig: ViewConfig); +module.exports = (RCTTextInputViewConfig: PartialViewConfig); diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 2bdd37eddc946e..5a26e2ebb947e7 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -8,25 +8,31 @@ * @format */ -const DeprecatedTextInputPropTypes = require('../../DeprecatedPropTypes/DeprecatedTextInputPropTypes'); -const Platform = require('../../Utilities/Platform'); -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); -const Text = require('../../Text/Text'); -const TextAncestor = require('../../Text/TextAncestor'); -const TextInputState = require('./TextInputState'); - -const invariant = require('invariant'); -const nullthrows = require('nullthrows'); -const setAndForwardRef = require('../../Utilities/setAndForwardRef'); +import * as React from 'react'; + +import DeprecatedTextInputPropTypes from '../../DeprecatedPropTypes/DeprecatedTextInputPropTypes'; + +import Platform from '../../Utilities/Platform'; +import StyleSheet, { + type TextStyleProp, + type ViewStyleProp, + type ColorValue, +} from '../../StyleSheet/StyleSheet'; +import Text from '../../Text/Text'; +import TextAncestor from '../../Text/TextAncestor'; +import TextInputState from './TextInputState'; +import invariant from 'invariant'; +import nullthrows from 'nullthrows'; +import setAndForwardRef from '../../Utilities/setAndForwardRef'; import usePressability from '../../Pressability/usePressability'; -import type {TextStyleProp, ViewStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ColorValue} from '../../StyleSheet/StyleSheet'; import type {ViewProps} from '../View/ViewPropTypes'; -import type {SyntheticEvent, ScrollEvent} from '../../Types/CoreEventTypes'; -import type {PressEvent} from '../../Types/CoreEventTypes'; +import type { + SyntheticEvent, + ScrollEvent, + PressEvent, +} from '../../Types/CoreEventTypes'; import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import type {TextInputNativeCommands} from './TextInputNativeCommands'; diff --git a/Libraries/Components/Touchable/BoundingDimensions.js b/Libraries/Components/Touchable/BoundingDimensions.js index b0a48d0eccd65c..114b950733df31 100644 --- a/Libraries/Components/Touchable/BoundingDimensions.js +++ b/Libraries/Components/Touchable/BoundingDimensions.js @@ -8,8 +8,7 @@ */ 'use strict'; - -const PooledClass = require('./PooledClass'); +import PooledClass from './PooledClass'; const twoArgumentPooler = PooledClass.twoArgumentPooler; diff --git a/Libraries/Components/Touchable/PooledClass.js b/Libraries/Components/Touchable/PooledClass.js index 4aee28a81c5ad7..1c9e940bd53df5 100644 --- a/Libraries/Components/Touchable/PooledClass.js +++ b/Libraries/Components/Touchable/PooledClass.js @@ -9,8 +9,7 @@ */ 'use strict'; - -const invariant = require('invariant'); +import invariant from 'invariant'; /** * Static poolers. Several custom versions for each potential number of diff --git a/Libraries/Components/Touchable/Position.js b/Libraries/Components/Touchable/Position.js index 37c9738dd4b844..5656bf9aaab912 100644 --- a/Libraries/Components/Touchable/Position.js +++ b/Libraries/Components/Touchable/Position.js @@ -8,8 +8,7 @@ */ 'use strict'; - -const PooledClass = require('./PooledClass'); +import PooledClass from './PooledClass'; const twoArgumentPooler = PooledClass.twoArgumentPooler; diff --git a/Libraries/Components/Touchable/Touchable.js b/Libraries/Components/Touchable/Touchable.js index 53c821ebc0849e..f59ba3ad4954ff 100644 --- a/Libraries/Components/Touchable/Touchable.js +++ b/Libraries/Components/Touchable/Touchable.js @@ -8,12 +8,12 @@ * @format */ -const BoundingDimensions = require('./BoundingDimensions'); -const Platform = require('../../Utilities/Platform'); -const Position = require('./Position'); -const React = require('react'); -const UIManager = require('../../ReactNative/UIManager'); -const SoundManager = require('../Sound/SoundManager'); +import * as React from 'react'; +import BoundingDimensions from './BoundingDimensions'; +import Platform from '../../Utilities/Platform'; +import Position from './Position'; +import UIManager from '../../ReactNative/UIManager'; +import SoundManager from '../Sound/SoundManager'; import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 6ae8cd850f7824..fc6da22f852c41 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -137,7 +137,7 @@ class TouchableOpacity extends React.Component { _createPressabilityConfig(): PressabilityConfig { return { cancelable: !this.props.rejectResponderTermination, - disabled: this.props.disabled, + disabled: this.props.disabled ?? this.props.accessibilityState?.disabled, hitSlop: this.props.hitSlop, delayLongPress: this.props.delayLongPress, delayPressIn: this.props.delayPressIn, @@ -215,13 +215,21 @@ class TouchableOpacity extends React.Component { ...eventHandlersWithoutBlurAndFocus } = this.state.pressability.getEventHandlers(); + const accessibilityState = + this.props.disabled != null + ? { + ...this.props.accessibilityState, + disabled: this.props.disabled, + } + : this.props.accessibilityState; + return ( { it('renders correctly', () => { - const instance = render.create( - + const instance = ReactTestRenderer.create( + + Touchable + , + ); + + expect(instance.toJSON()).toMatchSnapshot(); + }); + + it('renders in disabled state when a disabled prop is passed', () => { + const instance = ReactTestRenderer.create( + + Touchable + , + ); + + expect(instance.toJSON()).toMatchSnapshot(); + }); + + it('renders in disabled state when a key disabled in accessibilityState is passed', () => { + const instance = ReactTestRenderer.create( + Touchable , ); diff --git a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap index c1a2ee35013e24..2492d8c3a01da0 100644 --- a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap +++ b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap @@ -24,3 +24,63 @@ exports[`TouchableOpacity renders correctly 1`] = ` `; + +exports[`TouchableOpacity renders in disabled state when a disabled prop is passed 1`] = ` + + + Touchable + + +`; + +exports[`TouchableOpacity renders in disabled state when a key disabled in accessibilityState is passed 1`] = ` + + + Touchable + + +`; diff --git a/Libraries/Components/Touchable/ensurePositiveDelayProps.js b/Libraries/Components/Touchable/ensurePositiveDelayProps.js index 69dad5539faf2b..bd9b3028399cd0 100644 --- a/Libraries/Components/Touchable/ensurePositiveDelayProps.js +++ b/Libraries/Components/Touchable/ensurePositiveDelayProps.js @@ -9,8 +9,7 @@ */ 'use strict'; - -const invariant = require('invariant'); +import invariant from 'invariant'; const ensurePositiveDelayProps = function(props: any) { invariant( diff --git a/Libraries/Components/UnimplementedViews/UnimplementedView.js b/Libraries/Components/UnimplementedViews/UnimplementedView.js index 58804b7a772583..4bbb41060ff32f 100644 --- a/Libraries/Components/UnimplementedViews/UnimplementedView.js +++ b/Libraries/Components/UnimplementedViews/UnimplementedView.js @@ -9,9 +9,8 @@ */ 'use strict'; - -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); +import * as React from 'react'; +import StyleSheet from '../../StyleSheet/StyleSheet'; /** * Common implementation for a simple stubbed view. Simply applies the view's styles to the inner diff --git a/Libraries/Components/View/ReactNativeStyleAttributes.js b/Libraries/Components/View/ReactNativeStyleAttributes.js index ebd3c63df5614b..7ddf41e8352fd8 100644 --- a/Libraries/Components/View/ReactNativeStyleAttributes.js +++ b/Libraries/Components/View/ReactNativeStyleAttributes.js @@ -9,14 +9,12 @@ */ 'use strict'; - -const DeprecatedImageStylePropTypes = require('../../DeprecatedPropTypes/DeprecatedImageStylePropTypes'); -const DeprecatedTextStylePropTypes = require('../../DeprecatedPropTypes/DeprecatedTextStylePropTypes'); -const DeprecatedViewStylePropTypes = require('../../DeprecatedPropTypes/DeprecatedViewStylePropTypes'); - -const processColor = require('../../StyleSheet/processColor'); -const processTransform = require('../../StyleSheet/processTransform'); -const sizesDiffer = require('../../Utilities/differ/sizesDiffer'); +import DeprecatedImageStylePropTypes from '../../DeprecatedPropTypes/DeprecatedImageStylePropTypes'; +import DeprecatedTextStylePropTypes from '../../DeprecatedPropTypes/DeprecatedTextStylePropTypes'; +import DeprecatedViewStylePropTypes from '../../DeprecatedPropTypes/DeprecatedViewStylePropTypes'; +import processColor from '../../StyleSheet/processColor'; +import processTransform from '../../StyleSheet/processTransform'; +import sizesDiffer from '../../Utilities/differ/sizesDiffer'; type ReturnBoolType = (V) => true; type BoolifiedDeprecatedViewStylePropTypes = $ObjMap< diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index 50438910f2430f..da38aeef79085a 100644 --- a/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/Libraries/Components/View/ReactNativeViewAttributes.js @@ -9,8 +9,7 @@ */ 'use strict'; - -const ReactNativeStyleAttributes = require('./ReactNativeStyleAttributes'); +import ReactNativeStyleAttributes from './ReactNativeStyleAttributes'; const UIView = { pointerEvents: true, diff --git a/Libraries/Components/View/ReactNativeViewViewConfig.js b/Libraries/Components/View/ReactNativeViewViewConfig.js index 63fbe0fbeba3a3..ff0b6d837e17ad 100644 --- a/Libraries/Components/View/ReactNativeViewViewConfig.js +++ b/Libraries/Components/View/ReactNativeViewViewConfig.js @@ -8,7 +8,7 @@ * @format */ -import {type ViewConfig} from '../../Renderer/shims/ReactNativeTypes'; +import type {ViewConfig} from '../../Renderer/shims/ReactNativeTypes'; import ReactNativeViewViewConfigAndroid from './ReactNativeViewViewConfigAndroid'; import {Platform} from 'react-native'; diff --git a/Libraries/Components/View/ViewAccessibility.js b/Libraries/Components/View/ViewAccessibility.js index dd2056ae529ef1..ccdc6a6688a083 100644 --- a/Libraries/Components/View/ViewAccessibility.js +++ b/Libraries/Components/View/ViewAccessibility.js @@ -16,6 +16,7 @@ import type {SyntheticEvent} from '../../Types/CoreEventTypes'; export type AccessibilityRole = | 'none' | 'button' + | 'togglebutton' | 'link' | 'search' | 'image' diff --git a/Libraries/Components/Switch/SwitchInjection.js b/Libraries/Components/View/ViewInjection.js similarity index 69% rename from Libraries/Components/Switch/SwitchInjection.js rename to Libraries/Components/View/ViewInjection.js index 9b3130bfdb3a5c..d67512f5a57c47 100644 --- a/Libraries/Components/Switch/SwitchInjection.js +++ b/Libraries/Components/View/ViewInjection.js @@ -4,14 +4,10 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format - * @flow */ -'use strict'; - -import typeof Switch from './Switch'; - export default { - unstable_Switch: (null: ?Switch), + unstable_enableCollapsable: false, }; diff --git a/Libraries/Components/View/ViewNativeComponent.js b/Libraries/Components/View/ViewNativeComponent.js index 4ca5ec9cf3c479..4510d9bdab199b 100644 --- a/Libraries/Components/View/ViewNativeComponent.js +++ b/Libraries/Components/View/ViewNativeComponent.js @@ -13,8 +13,10 @@ import {type HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import Platform from '../../Utilities/Platform'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import ReactNativeViewViewConfigAndroid from './ReactNativeViewViewConfigAndroid'; +import ViewInjection from './ViewInjection'; import {type ViewProps as Props} from './ViewPropTypes'; import * as React from 'react'; +import ReactNativeViewConfigRegistry from '../../Renderer/shims/ReactNativeViewConfigRegistry'; const ViewNativeComponent: HostComponent = NativeComponentRegistry.get( 'RCTView', @@ -24,6 +26,14 @@ const ViewNativeComponent: HostComponent = NativeComponentRegistry.get>, diff --git a/Libraries/Components/__tests__/Slider-test.js b/Libraries/Components/__tests__/Slider-test.js new file mode 100644 index 00000000000000..5e3a9f47f86b77 --- /dev/null +++ b/Libraries/Components/__tests__/Slider-test.js @@ -0,0 +1,37 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +import * as React from 'react'; +import ReactTestRenderer from 'react-test-renderer'; +import Slider from '../Slider/Slider'; + +describe('', () => { + it('should render as expected', () => { + expect(ReactTestRenderer.create()).toMatchSnapshot(); + }); + + it('should set disabled as false', () => { + // Slider component should set disabled prop as false by default + expect(ReactTestRenderer.create()).toMatchSnapshot(); + expect( + ReactTestRenderer.create( + , + ), + ).toMatchSnapshot(); + }); + it('should set disabled as true', () => { + expect(ReactTestRenderer.create()).toMatchSnapshot(); + expect( + ReactTestRenderer.create( + , + ), + ).toMatchSnapshot(); + }); +}); diff --git a/Libraries/Components/__tests__/__snapshots__/Slider-test.js.snap b/Libraries/Components/__tests__/__snapshots__/Slider-test.js.snap new file mode 100644 index 00000000000000..63c3e3507a55c7 --- /dev/null +++ b/Libraries/Components/__tests__/__snapshots__/Slider-test.js.snap @@ -0,0 +1,121 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` should render as expected 1`] = ` + +`; + +exports[` should set disabled as false 1`] = ` + +`; + +exports[` should set disabled as false 2`] = ` + +`; + +exports[` should set disabled as true 1`] = ` + +`; + +exports[` should set disabled as true 2`] = ` + +`; diff --git a/Libraries/Core/Devtools/parseErrorStack.js b/Libraries/Core/Devtools/parseErrorStack.js index 1c4e1f67535640..185ddcb7e75332 100644 --- a/Libraries/Core/Devtools/parseErrorStack.js +++ b/Libraries/Core/Devtools/parseErrorStack.js @@ -15,16 +15,6 @@ import type {HermesParsedStack} from './parseHermesStack'; const parseHermesStack = require('./parseHermesStack'); -// $FlowFixMe[incompatible-exact] -export type ExtendedError = Error & - interface { - jsEngine?: string, - preventSymbolication?: boolean, - componentStack?: string, - forceRedbox?: boolean, - isComponentError?: boolean, - }; - function convertHermesStack(stack: HermesParsedStack): Array { const frames = []; for (const entry of stack.entries) { diff --git a/Libraries/Core/ExceptionsManager.js b/Libraries/Core/ExceptionsManager.js index 6da6d8a4a302cb..0b394e2c154726 100644 --- a/Libraries/Core/ExceptionsManager.js +++ b/Libraries/Core/ExceptionsManager.js @@ -10,7 +10,7 @@ 'use strict'; -import type {ExtendedError} from './Devtools/parseErrorStack'; +import type {ExtendedError} from './ExtendedError'; import type {ExceptionData} from './NativeExceptionsManager'; class SyntheticError extends Error { @@ -105,35 +105,37 @@ function reportException( } if (__DEV__ && isHandledByLogBox) { - const LogBoxData = require('../LogBox/Data/LogBoxData'); - LogBoxData.addException({ + const LogBox = require('../LogBox/LogBox'); + LogBox.addException({ ...data, isComponentError: !!e.isComponentError, }); } - NativeExceptionsManager.reportException(data); + if (e.type !== 'warn') { + NativeExceptionsManager.reportException(data); - if (__DEV__ && !global.RN$Express) { - if (e.preventSymbolication === true) { - return; + if (__DEV__ && !global.RN$Express) { + if (e.preventSymbolication === true) { + return; + } + const symbolicateStackTrace = require('./Devtools/symbolicateStackTrace'); + symbolicateStackTrace(stack) + .then(({stack: prettyStack}) => { + if (prettyStack) { + NativeExceptionsManager.updateExceptionMessage( + data.message, + prettyStack, + currentExceptionID, + ); + } else { + throw new Error('The stack is null'); + } + }) + .catch(error => { + console.log('Unable to symbolicate stack trace: ' + error.message); + }); } - const symbolicateStackTrace = require('./Devtools/symbolicateStackTrace'); - symbolicateStackTrace(stack) - .then(({stack: prettyStack}) => { - if (prettyStack) { - NativeExceptionsManager.updateExceptionMessage( - data.message, - prettyStack, - currentExceptionID, - ); - } else { - throw new Error('The stack is null'); - } - }) - .catch(error => { - console.log('Unable to symbolicate stack trace: ' + error.message); - }); } } else if (reportToConsole) { // we feed back into console.error, to make sure any methods that are @@ -175,9 +177,9 @@ function handleException(e: mixed, isFatal: boolean) { } } -function reactConsoleErrorHandler() { +function reactConsoleErrorHandler(...args) { // bubble up to any original handlers - console._errorOriginal.apply(console, arguments); + console._errorOriginal(...args); if (!console.reportErrorsAsExceptions) { return; } @@ -213,31 +215,33 @@ function reactConsoleErrorHandler() { return; } - if (arguments[0] && arguments[0].stack) { + let error; + + const firstArg = args[0]; + if (firstArg?.stack) { // reportException will console.error this with high enough fidelity. - reportException( - arguments[0], - /* isFatal */ false, - /*reportToConsole*/ false, - ); + error = firstArg; } else { const stringifySafe = require('../Utilities/stringifySafe').default; - const str = Array.prototype.map - .call(arguments, value => - typeof value === 'string' ? value : stringifySafe(value), - ) - .join(' '); - - if (str.slice(0, 9) === 'Warning: ') { + if (typeof firstArg === 'string' && firstArg.startsWith('Warning: ')) { // React warnings use console.error so that a stack trace is shown, but // we don't (currently) want these to show a redbox // (Note: Logic duplicated in polyfills/console.js.) return; } - const error: ExtendedError = new SyntheticError(str); + const message = args + .map(arg => (typeof arg === 'string' ? arg : stringifySafe(arg))) + .join(' '); + + error = new SyntheticError(message); error.name = 'console.error'; - reportException(error, /* isFatal */ false, /*reportToConsole*/ false); } + + reportException( + error, + false, // isFatal + false, // reportToConsole + ); } /** diff --git a/Libraries/Core/ExtendedError.js b/Libraries/Core/ExtendedError.js new file mode 100644 index 00000000000000..88e6331ced0c98 --- /dev/null +++ b/Libraries/Core/ExtendedError.js @@ -0,0 +1,19 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +export type ExtendedError = Error & { + jsEngine?: string, + preventSymbolication?: boolean, + componentStack?: string, + forceRedbox?: boolean, + isComponentError?: boolean, + type?: string, + ... +}; diff --git a/Libraries/Core/InitializeCore.js b/Libraries/Core/InitializeCore.js index e00120aa4b48a5..e30baa2eb72564 100644 --- a/Libraries/Core/InitializeCore.js +++ b/Libraries/Core/InitializeCore.js @@ -43,6 +43,7 @@ require('./setUpSegmentFetcher'); if (__DEV__) { require('./checkNativeVersion'); require('./setUpDeveloperTools'); + require('../LogBox/LogBox').install(); } const GlobalPerformanceLogger = require('../Utilities/GlobalPerformanceLogger'); diff --git a/Libraries/Core/ReactFiberErrorDialog.js b/Libraries/Core/ReactFiberErrorDialog.js index d329e2d27bd4cb..759c30b94a5468 100644 --- a/Libraries/Core/ReactFiberErrorDialog.js +++ b/Libraries/Core/ReactFiberErrorDialog.js @@ -8,6 +8,10 @@ * @flow strict-local */ +import {handleException, SyntheticError} from './ExceptionsManager'; + +import type {ExtendedError} from './ExtendedError'; + export type CapturedError = { +componentStack: string, +error: mixed, @@ -15,38 +19,38 @@ export type CapturedError = { ... }; -import type {ExtendedError} from './Devtools/parseErrorStack'; - -import {handleException, SyntheticError} from './ExceptionsManager'; +const ReactFiberErrorDialog = { + /** + * Intercept lifecycle errors and ensure they are shown with the correct stack + * trace within the native redbox component. + */ + showErrorDialog({componentStack, error: errorValue}: CapturedError): boolean { + let error: ?ExtendedError; + + // Typically, `errorValue` should be an error. However, other values such as + // strings (or even null) are sometimes thrown. + if (errorValue instanceof Error) { + error = (errorValue: ExtendedError); + } else if (typeof errorValue === 'string') { + error = (new SyntheticError(errorValue): ExtendedError); + } else { + error = (new SyntheticError('Unspecified error'): ExtendedError); + } + try { + error.componentStack = componentStack; + error.isComponentError = true; + } catch { + // Ignored. + } + + handleException(error, false); + + // 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; + }, +}; -/** - * Intercept lifecycle errors and ensure they are shown with the correct stack - * trace within the native redbox component. - */ -function showErrorDialog(capturedError: CapturedError): boolean { - const {componentStack, error} = capturedError; - - let errorToHandle; - - // Typically Errors are thrown but eg strings or null can be thrown as well. - if (error instanceof Error) { - errorToHandle = (error: ExtendedError); - } else if (typeof error === 'string') { - errorToHandle = (new SyntheticError(error): ExtendedError); - } else { - errorToHandle = (new SyntheticError('Unspecified error'): ExtendedError); - } - try { - errorToHandle.componentStack = componentStack; - errorToHandle.isComponentError = true; - } catch (e) {} - handleException(errorToHandle, false); - - // 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; -} - -module.exports = {showErrorDialog}; +export default ReactFiberErrorDialog; diff --git a/Libraries/Core/__tests__/ExceptionsManager-test.js b/Libraries/Core/__tests__/ExceptionsManager-test.js index 71e3be3cb94164..228bd9c2b3b8ec 100644 --- a/Libraries/Core/__tests__/ExceptionsManager-test.js +++ b/Libraries/Core/__tests__/ExceptionsManager-test.js @@ -10,6 +10,9 @@ 'use strict'; +const ExceptionsManager = require('../ExceptionsManager'); +const NativeExceptionsManager = require('../NativeExceptionsManager').default; +const ReactFiberErrorDialog = require('../ReactFiberErrorDialog').default; const fs = require('fs'); const path = require('path'); @@ -23,10 +26,8 @@ const capturedErrorDefaults = { }; describe('ExceptionsManager', () => { - let ReactFiberErrorDialog, - ExceptionsManager, - NativeExceptionsManager, - nativeReportException; + let nativeReportException; + beforeEach(() => { jest.resetModules(); jest.mock('../NativeExceptionsManager', () => { @@ -46,11 +47,8 @@ describe('ExceptionsManager', () => { return {stack}; }, ); - jest.spyOn(console, 'error').mockImplementation(() => {}); - ReactFiberErrorDialog = require('../ReactFiberErrorDialog'); - NativeExceptionsManager = require('../NativeExceptionsManager').default; + jest.spyOn(console, 'error').mockReturnValue(undefined); nativeReportException = NativeExceptionsManager.reportException; - ExceptionsManager = require('../ExceptionsManager'); }); afterEach(() => { @@ -360,6 +358,18 @@ describe('ExceptionsManager', () => { expect(mockError.mock.calls[0]).toEqual(args); }); + test('logging a warning-looking object', () => { + // Forces `strignifySafe` to invoke `toString()`. + const object = {toString: () => 'Warning: Some error may have happened'}; + object.cycle = object; + + const args = [object]; + + console.error(...args); + + expect(nativeReportException).toHaveBeenCalled(); + }); + test('reportErrorsAsExceptions = false', () => { console.reportErrorsAsExceptions = false; const message = 'Some error happened'; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedViewAccessibility.js b/Libraries/DeprecatedPropTypes/DeprecatedViewAccessibility.js index 77c4146a865f5b..ef82aa5c7dedfe 100644 --- a/Libraries/DeprecatedPropTypes/DeprecatedViewAccessibility.js +++ b/Libraries/DeprecatedPropTypes/DeprecatedViewAccessibility.js @@ -15,6 +15,7 @@ module.exports = { DeprecatedAccessibilityRoles: [ 'none', 'button', + 'togglebutton', 'link', 'search', 'image', diff --git a/Libraries/EventEmitter/NativeEventEmitter.js b/Libraries/EventEmitter/NativeEventEmitter.js index b3f7248071704a..5a00822edb4419 100644 --- a/Libraries/EventEmitter/NativeEventEmitter.js +++ b/Libraries/EventEmitter/NativeEventEmitter.js @@ -54,7 +54,7 @@ export default class NativeEventEmitter if (nativeModule && hasAddListener && hasRemoveListeners) { this._nativeModule = nativeModule; - } else { + } else if (nativeModule != null) { if (!hasAddListener) { console.warn( '`new NativeEventEmitter()` was called with a non-null argument without the required `addListener` method.', diff --git a/Libraries/EventEmitter/RCTEventEmitter.js b/Libraries/EventEmitter/RCTEventEmitter.js index 8001a7cf36a005..fd0ac72eaf9995 100644 --- a/Libraries/EventEmitter/RCTEventEmitter.js +++ b/Libraries/EventEmitter/RCTEventEmitter.js @@ -14,7 +14,11 @@ const BatchedBridge = require('../BatchedBridge/BatchedBridge'); const RCTEventEmitter = { register(eventEmitter: any) { - BatchedBridge.registerCallableModule('RCTEventEmitter', eventEmitter); + if (global.RN$Bridgeless) { + global.RN$registerCallableModule('RCTEventEmitter', () => eventEmitter); + } else { + BatchedBridge.registerCallableModule('RCTEventEmitter', eventEmitter); + } }, }; diff --git a/Libraries/FBLazyVector/BUCK b/Libraries/FBLazyVector/BUCK index d526718e2de05b..089bca264b12ab 100644 --- a/Libraries/FBLazyVector/BUCK +++ b/Libraries/FBLazyVector/BUCK @@ -2,7 +2,11 @@ load("//tools/build_defs/oss:rn_defs.bzl", "fb_apple_library") fb_apple_library( name = "FBLazyVector", - autoglob = True, + exported_headers = [ + "FBLazyVector/FBLazyIterator.h", + "FBLazyVector/FBLazyVector.h", + ], + autoglob = False, complete_nullability = True, contacts = ["oncall+react_native@xmail.facebook.com"], enable_exceptions = False, diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index 08f81303528264..2f9aec0d6666a9 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -27,6 +27,7 @@ import NativeImageLoaderAndroid from './NativeImageLoaderAndroid'; const TextInlineImageNativeComponent = require('./TextInlineImageNativeComponent'); import type {ImageProps as ImagePropsType} from './ImageProps'; +import type {RootTag} from '../Types/RootTagTypes'; let _requestId = 1; function generateRequestId() { @@ -195,7 +196,7 @@ function getSizeWithHeaders( function prefetchWithMetadata( url: string, queryRootName: string, - rootTag?: ?number, + rootTag?: ?RootTag, callback: ?Function, ): any { // TODO: T79192300 Log queryRootName and rootTag diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index 850ccfa7067bdc..45905817540189 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -23,6 +23,7 @@ import type {ImageStyleProp} from '../StyleSheet/StyleSheet'; import NativeImageLoaderIOS from './NativeImageLoaderIOS'; import ImageViewNativeComponent from './ImageViewNativeComponent'; +import type {RootTag} from 'react-native/Libraries/Types/RootTagTypes'; function getSize( uri: string, @@ -60,13 +61,15 @@ function getSizeWithHeaders( function prefetchWithMetadata( url: string, queryRootName: string, - rootTag?: ?number, + rootTag?: ?RootTag, ): any { if (NativeImageLoaderIOS.prefetchImageWithMetadata) { // number params like rootTag cannot be nullable before TurboModules is available return NativeImageLoaderIOS.prefetchImageWithMetadata( url, queryRootName, + // NOTE: RootTag type + // $FlowFixMe[incompatible-call] RootTag: number is incompatible with RootTag rootTag ? rootTag : 0, ); } else { diff --git a/Libraries/Image/NativeImageLoaderIOS.js b/Libraries/Image/NativeImageLoaderIOS.js index cbebf34e2d1167..91c65a6e245cad 100644 --- a/Libraries/Image/NativeImageLoaderIOS.js +++ b/Libraries/Image/NativeImageLoaderIOS.js @@ -8,6 +8,7 @@ * @format */ +import type {RootTag} from '../TurboModule/RCTExport'; import type {TurboModule} from '../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; @@ -27,7 +28,7 @@ export interface Spec extends TurboModule { +prefetchImageWithMetadata?: ( uri: string, queryRootName: string, - rootTag: number, + rootTag: RootTag, ) => Promise; +queryCache: (uris: Array) => Promise; } diff --git a/Libraries/Image/RCTImageLoader.h b/Libraries/Image/RCTImageLoader.h index b7040e1a4c77d0..da0df284e6f6b8 100644 --- a/Libraries/Image/RCTImageLoader.h +++ b/Libraries/Image/RCTImageLoader.h @@ -21,8 +21,8 @@ - (instancetype)init; - (instancetype)initWithRedirectDelegate:(id)redirectDelegate NS_DESIGNATED_INITIALIZER; - (instancetype)initWithRedirectDelegate:(id)redirectDelegate - loadersProvider:(NSArray> * (^)(void))getLoaders - decodersProvider:(NSArray> * (^)(void))getDecoders; + loadersProvider:(NSArray> * (^)(RCTModuleRegistry *))getLoaders + decodersProvider:(NSArray> * (^)(RCTModuleRegistry *))getDecoders; @end /** diff --git a/Libraries/Image/RCTImageLoader.mm b/Libraries/Image/RCTImageLoader.mm index cf63f937eeeaf6..90bdfbb01296a0 100644 --- a/Libraries/Image/RCTImageLoader.mm +++ b/Libraries/Image/RCTImageLoader.mm @@ -80,8 +80,8 @@ - (void)setReactDecodedImageBytes:(NSInteger)bytes @implementation RCTImageLoader { - NSArray> * (^_loadersProvider)(void); - NSArray> * (^_decodersProvider)(void); + NSArray> * (^_loadersProvider)(RCTModuleRegistry *); + NSArray> * (^_decodersProvider)(RCTModuleRegistry *); NSArray> *_loaders; NSArray> *_decoders; NSOperationQueue *_imageDecodeQueue; @@ -123,8 +123,8 @@ - (instancetype)initWithRedirectDelegate:(id)redirectD } - (instancetype)initWithRedirectDelegate:(id)redirectDelegate - loadersProvider:(NSArray> * (^)(void))getLoaders - decodersProvider:(NSArray> * (^)(void))getHandlers + loadersProvider:(NSArray> * (^)(RCTModuleRegistry *))getLoaders + decodersProvider:(NSArray> * (^)(RCTModuleRegistry *))getHandlers { if (self = [self initWithRedirectDelegate:redirectDelegate]) { _loadersProvider = getLoaders; @@ -178,7 +178,7 @@ - (void)setImageCache:(id)cache // Get loaders, sorted in reverse priority order (highest priority first) if (_loadersProvider) { - _loaders = _loadersProvider(); + _loaders = _loadersProvider(self.moduleRegistry); } else { RCTAssert(_bridge, @"Trying to find RCTImageURLLoaders and bridge not set."); _loaders = [_bridge modulesConformingToProtocol:@protocol(RCTImageURLLoader)]; @@ -245,7 +245,7 @@ - (void)setImageCache:(id)cache // Get decoders, sorted in reverse priority order (highest priority first) if (_decodersProvider) { - _decoders = _decodersProvider(); + _decoders = _decodersProvider(self.moduleRegistry); } else { RCTAssert(_bridge, @"Trying to find RCTImageDataDecoders and bridge not set."); _decoders = [_bridge modulesConformingToProtocol:@protocol(RCTImageDataDecoder)]; diff --git a/Libraries/Image/RCTImagePlugins.mm b/Libraries/Image/RCTImagePlugins.mm index 3cde9e95650e5b..1e03e76066e244 100644 --- a/Libraries/Image/RCTImagePlugins.mm +++ b/Libraries/Image/RCTImagePlugins.mm @@ -17,7 +17,8 @@ #import Class RCTImageClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"GIFImageDecoder", RCTGIFImageDecoderCls}, {"ImageEditingManager", RCTImageEditingManagerCls}, {"ImageLoader", RCTImageLoaderCls}, @@ -25,8 +26,8 @@ Class RCTImageClassProvider(const char *name) { {"LocalAssetImageLoader", RCTLocalAssetImageLoaderCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/Libraries/Image/React-RCTImage.podspec b/Libraries/Image/React-RCTImage.podspec index b6acc57d5d80f1..73fda1a8e35119 100644 --- a/Libraries/Image/React-RCTImage.podspec +++ b/Libraries/Image/React-RCTImage.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTImage" diff --git a/Libraries/LinkingIOS/RCTLinkingPlugins.mm b/Libraries/LinkingIOS/RCTLinkingPlugins.mm index b2549557558b23..b5993a9b306ff5 100644 --- a/Libraries/LinkingIOS/RCTLinkingPlugins.mm +++ b/Libraries/LinkingIOS/RCTLinkingPlugins.mm @@ -17,12 +17,13 @@ #import Class RCTLinkingClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"LinkingManager", RCTLinkingManagerCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/Libraries/LinkingIOS/React-RCTLinking.podspec b/Libraries/LinkingIOS/React-RCTLinking.podspec index f18e0664f26057..1c45bf44a171b1 100644 --- a/Libraries/LinkingIOS/React-RCTLinking.podspec +++ b/Libraries/LinkingIOS/React-RCTLinking.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTLinking" diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index a7c1567b3f607a..976b22705e5df3 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -20,7 +20,6 @@ const ViewabilityHelper = require('./ViewabilityHelper'); const flattenStyle = require('../StyleSheet/flattenStyle'); const infoLog = require('../Utilities/infoLog'); const invariant = require('invariant'); -import VirtualizedListInjection from './VirtualizedListInjection'; import { keyExtractor as defaultKeyExtractor, @@ -1353,22 +1352,18 @@ class VirtualizedList extends React.PureComponent { this._scrollMetrics.visibleLength = scrollMetrics.visibleLength; this._scrollMetrics.offset = scrollMetrics.offset; - if ( - VirtualizedListInjection?.unstable_enableVirtualizedListRemeasureChildrenIfNeeded - ) { - // If metrics of the scrollView changed, then we triggered remeasure for child list - // to ensure VirtualizedList has the right information. - this._cellKeysToChildListKeys.forEach(childListKeys => { - if (childListKeys) { - for (let childKey of childListKeys) { - const childList = this._nestedChildLists.get(childKey); - childList && - childList.ref && - childList.ref.measureLayoutRelativeToContainingList(); - } + // If metrics of the scrollView changed, then we triggered remeasure for child list + // to ensure VirtualizedList has the right information. + this._cellKeysToChildListKeys.forEach(childListKeys => { + if (childListKeys) { + for (let childKey of childListKeys) { + const childList = this._nestedChildLists.get(childKey); + childList && + childList.ref && + childList.ref.measureLayoutRelativeToContainingList(); } - }); - } + } + }); } }, error => { diff --git a/Libraries/Lists/VirtualizedSectionList.js b/Libraries/Lists/VirtualizedSectionList.js index 2b64a9bba917cb..194352180be0d6 100644 --- a/Libraries/Lists/VirtualizedSectionList.js +++ b/Libraries/Lists/VirtualizedSectionList.js @@ -8,17 +8,11 @@ * @format */ -'use strict'; - -const React = require('react'); -const View = require('../Components/View/View'); -const VirtualizedList = require('./VirtualizedList'); - -const invariant = require('invariant'); - +import invariant from 'invariant'; import type {ViewToken} from './ViewabilityHelper'; import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils'; -import VirtualizedSectionListInjection from './VirtualizedSectionListInjection'; +import {View, VirtualizedList} from 'react-native'; +import * as React from 'react'; type Item = any; @@ -386,11 +380,13 @@ class VirtualizedSectionList< item={item} leadingItem={info.leadingItem} leadingSection={info.leadingSection} - onUpdateSeparator={this._onUpdateSeparator} prevCellKey={(this._subExtractor(index - 1) || {}).key} - ref={ref => { - this._cellRefs[info.key] = ref; - }} + // Callback to provide updateHighlight for this item + setSelfHighlightCallback={this._setUpdateHighlightFor} + setSelfUpdatePropsCallback={this._setUpdatePropsFor} + // Provide child ability to set highlight/updateProps for previous item using prevCellKey + updateHighlightFor={this._updateHighlightFor} + updatePropsFor={this._updatePropsFor} renderItem={renderItem} section={info.section} trailingItem={info.trailingItem} @@ -401,9 +397,34 @@ class VirtualizedSectionList< } }; - _onUpdateSeparator = (key: string, newProps: Object) => { - const ref = this._cellRefs[key]; - ref && ref.updateSeparatorProps(newProps); + _updatePropsFor = (cellKey, value) => { + const updateProps = this._updatePropsMap[cellKey]; + if (updateProps != null) { + updateProps(value); + } + }; + + _updateHighlightFor = (cellKey, value) => { + const updateHighlight = this._updateHighlightMap[cellKey]; + if (updateHighlight != null) { + updateHighlight(value); + } + }; + + _setUpdateHighlightFor = (cellKey, updateHighlightFn) => { + if (updateHighlightFn != null) { + this._updateHighlightMap[cellKey] = updateHighlightFn; + } else { + delete this._updateHighlightFor[cellKey]; + } + }; + + _setUpdatePropsFor = (cellKey, updatePropsFn) => { + if (updatePropsFn != null) { + this._updatePropsMap[cellKey] = updatePropsFn; + } else { + delete this._updatePropsMap[cellKey]; + } }; _getSeparatorComponent( @@ -430,7 +451,8 @@ class VirtualizedSectionList< return null; } - _cellRefs = {}; + _updateHighlightMap = {}; + _updatePropsMap = {}; _listRef: ?React.ElementRef; _captureRef = ref => { this._listRef = ref; @@ -452,142 +474,140 @@ type ItemWithSeparatorProps = $ReadOnly<{| cellKey: string, index: number, item: Item, - onUpdateSeparator: (cellKey: string, newProps: Object) => void, + setSelfHighlightCallback: ( + cellKey: string, + updateFn: ?(boolean) => void, + ) => void, + setSelfUpdatePropsCallback: ( + cellKey: string, + updateFn: ?(boolean) => void, + ) => void, prevCellKey?: ?string, + updateHighlightFor: (prevCellKey: string, value: boolean) => void, + updatePropsFor: (prevCellKey: string, value: Object) => void, renderItem: Function, inverted: boolean, |}>; -type ItemWithSeparatorState = { - separatorProps: $ReadOnly<{| - highlighted: false, - ...ItemWithSeparatorCommonProps, - |}>, - leadingSeparatorProps: $ReadOnly<{| - highlighted: false, - ...ItemWithSeparatorCommonProps, - |}>, - ... -}; - -class ItemWithSeparator extends React.Component< - ItemWithSeparatorProps, - ItemWithSeparatorState, -> { - state = { - separatorProps: { - highlighted: false, - leadingItem: this.props.item, - leadingSection: this.props.leadingSection, - section: this.props.section, - trailingItem: this.props.trailingItem, - trailingSection: this.props.trailingSection, - }, - leadingSeparatorProps: { - highlighted: false, - leadingItem: this.props.leadingItem, - leadingSection: this.props.leadingSection, - section: this.props.section, - trailingItem: this.props.item, - trailingSection: this.props.trailingSection, - }, - }; - - _separators = { +function ItemWithSeparator(props: ItemWithSeparatorProps): React.Node { + const { + LeadingSeparatorComponent, + // this is the trailing separator and is associated with this item + SeparatorComponent, + cellKey, + prevCellKey, + setSelfHighlightCallback, + updateHighlightFor, + setSelfUpdatePropsCallback, + updatePropsFor, + item, + index, + section, + inverted, + } = props; + + const [ + leadingSeparatorHiglighted, + setLeadingSeparatorHighlighted, + ] = React.useState(false); + + const [separatorHighlighted, setSeparatorHighlighted] = React.useState(false); + + const [leadingSeparatorProps, setLeadingSeparatorProps] = React.useState({ + leadingItem: props.leadingItem, + leadingSection: props.leadingSection, + section: props.section, + trailingItem: props.item, + trailingSection: props.trailingSection, + }); + const [separatorProps, setSeparatorProps] = React.useState({ + leadingItem: props.item, + leadingSection: props.leadingSection, + section: props.section, + trailingItem: props.trailingItem, + trailingSection: props.trailingSection, + }); + + React.useEffect(() => { + setSelfHighlightCallback(cellKey, setSeparatorHighlighted); + setSelfUpdatePropsCallback(cellKey, setSeparatorProps); + + return () => { + setSelfUpdatePropsCallback(cellKey, null); + setSelfHighlightCallback(cellKey, null); + }; + }, [ + cellKey, + setSelfHighlightCallback, + setSeparatorProps, + setSelfUpdatePropsCallback, + ]); + + const separators = { highlight: () => { - ['leading', 'trailing'].forEach(s => - this._separators.updateProps(s, {highlighted: true}), - ); + setLeadingSeparatorHighlighted(true); + setSeparatorHighlighted(true); + if (prevCellKey != null) { + updateHighlightFor(prevCellKey, true); + } }, unhighlight: () => { - ['leading', 'trailing'].forEach(s => - this._separators.updateProps(s, {highlighted: false}), - ); + setLeadingSeparatorHighlighted(false); + setSeparatorHighlighted(false); + if (prevCellKey != null) { + updateHighlightFor(prevCellKey, false); + } }, - updateProps: (select: 'leading' | 'trailing', newProps: Object) => { - const {LeadingSeparatorComponent, cellKey, prevCellKey} = this.props; - if (select === 'leading' && LeadingSeparatorComponent != null) { - this.setState(state => ({ - leadingSeparatorProps: {...state.leadingSeparatorProps, ...newProps}, - })); - } else { - this.props.onUpdateSeparator( - (select === 'leading' && prevCellKey) || cellKey, - newProps, - ); + updateProps: ( + select: 'leading' | 'trailing', + newProps: $Shape, + ) => { + if (select === 'leading') { + if (LeadingSeparatorComponent != null) { + setLeadingSeparatorProps({...leadingSeparatorProps, ...newProps}); + } else if (prevCellKey != null) { + // update the previous item's separator + updatePropsFor(prevCellKey, {...leadingSeparatorProps, ...newProps}); + } + } else if (select === 'trailing' && SeparatorComponent != null) { + setSeparatorProps({...separatorProps, ...newProps}); } }, }; - - static getDerivedStateFromProps( - props: ItemWithSeparatorProps, - prevState: ItemWithSeparatorState, - ): ?ItemWithSeparatorState { - return { - separatorProps: { - ...prevState.separatorProps, - leadingItem: props.item, - leadingSection: props.leadingSection, - section: props.section, - trailingItem: props.trailingItem, - trailingSection: props.trailingSection, - }, - leadingSeparatorProps: { - ...prevState.leadingSeparatorProps, - leadingItem: props.leadingItem, - leadingSection: props.leadingSection, - section: props.section, - trailingItem: props.item, - trailingSection: props.trailingSection, - }, - }; - } - - updateSeparatorProps(newProps: Object) { - this.setState(state => ({ - separatorProps: {...state.separatorProps, ...newProps}, - })); - } - - render() { - const { - LeadingSeparatorComponent, - SeparatorComponent, - item, - index, - section, - inverted, - } = this.props; - const element = this.props.renderItem({ - item, - index, - section, - separators: this._separators, - }); - const leadingSeparator = LeadingSeparatorComponent != null && ( - - ); - const separator = SeparatorComponent != null && ( - - ); - return leadingSeparator || separator ? ( - - {inverted === false ? leadingSeparator : separator} - {element} - {inverted === false ? separator : leadingSeparator} - - ) : ( - element - ); - } + const element = props.renderItem({ + item, + index, + section, + separators, + }); + const leadingSeparator = LeadingSeparatorComponent != null && ( + + ); + const separator = SeparatorComponent != null && ( + + ); + return leadingSeparator || separator ? ( + + {inverted === false ? leadingSeparator : separator} + {element} + {inverted === false ? separator : leadingSeparator} + + ) : ( + element + ); } -const VSLToExport: React.AbstractComponent< +module.exports = (VirtualizedSectionList: React.AbstractComponent< React.ElementConfig, $ReadOnly<{ getListRef: () => ?React.ElementRef, scrollToLocation: (params: ScrollToLocationParamsType) => void, ... }>, -> = VirtualizedSectionListInjection.unstable_VSL ?? VirtualizedSectionList; -module.exports = VSLToExport; +>); diff --git a/Libraries/Lists/VirtualizedSectionListInjection.js b/Libraries/Lists/VirtualizedSectionListInjection.js deleted file mode 100644 index fa1a00adbc51ac..00000000000000 --- a/Libraries/Lists/VirtualizedSectionListInjection.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @flow - */ - -'use strict'; - -import typeof VirtualizedSectionList from './VirtualizedSectionList'; - -export default { - unstable_VSL: (null: ?VirtualizedSectionList), -}; diff --git a/Libraries/LogBox/Data/LogBoxData.js b/Libraries/LogBox/Data/LogBoxData.js index b9890449b4c0c7..d247c8d8d99862 100644 --- a/Libraries/LogBox/Data/LogBoxData.js +++ b/Libraries/LogBox/Data/LogBoxData.js @@ -21,7 +21,7 @@ import type { ExtendedExceptionData, } from './parseLogBoxLog'; import parseErrorStack from '../../Core/Devtools/parseErrorStack'; -import type {ExtendedError} from '../../Core/Devtools/parseErrorStack'; +import type {ExtendedError} from '../../Core/ExtendedError'; import NativeLogBox from '../../NativeModules/specs/NativeLogBox'; export type LogBoxLogs = Set; export type LogData = $ReadOnly<{| diff --git a/Libraries/LogBox/LogBox.js b/Libraries/LogBox/LogBox.js index 4e85842249c56d..23492d721656f8 100644 --- a/Libraries/LogBox/LogBox.js +++ b/Libraries/LogBox/LogBox.js @@ -11,10 +11,24 @@ import Platform from '../Utilities/Platform'; import RCTLog from '../Utilities/RCTLog'; -import type {IgnorePattern} from './Data/LogBoxData'; +import type {IgnorePattern, LogData} from './Data/LogBoxData'; +import type {ExtendedExceptionData} from './Data/parseLogBoxLog'; + +export type {LogData, ExtendedExceptionData, IgnorePattern}; let LogBox; +interface ILogBox { + install(): void; + uninstall(): void; + isInstalled(): boolean; + ignoreLogs($ReadOnlyArray): void; + ignoreAllLogs(?boolean): void; + clearAllLogs(): void; + addLog(log: LogData): void; + addException(error: ExtendedExceptionData): void; +} + /** * LogBox displays logs in the app. */ @@ -22,45 +36,44 @@ if (__DEV__) { const LogBoxData = require('./Data/LogBoxData'); const {parseLogBoxLog, parseInterpolation} = require('./Data/parseLogBoxLog'); - // LogBox needs to insert itself early, - // in order to access the component stacks appended by React DevTools. - const {error, warn} = console; - let errorImpl = error.bind(console); - let warnImpl = warn.bind(console); + let originalConsoleError; + let originalConsoleWarn; + let consoleErrorImpl; + let consoleWarnImpl; - (console: any).error = function(...args) { - errorImpl(...args); - }; - (console: any).warn = function(...args) { - warnImpl(...args); - }; + let isLogBoxInstalled: boolean = false; LogBox = { - ignoreLogs: (patterns: $ReadOnlyArray): void => { - LogBoxData.addIgnorePatterns(patterns); - }, + install(): void { + if (isLogBoxInstalled) { + return; + } - ignoreAllLogs: (value?: ?boolean): void => { - LogBoxData.setDisabled(value == null ? true : value); - }, + isLogBoxInstalled = true; - uninstall: (): void => { - errorImpl = error; - warnImpl = warn; - delete (console: any).disableLogBox; - }, - - install: (): void => { // Trigger lazy initialization of module. require('../NativeModules/specs/NativeLogBox'); - errorImpl = function(...args) { - registerError(...args); - }; + // IMPORTANT: we only overwrite `console.error` and `console.warn` once. + // When we uninstall we keep the same reference and only change its + // internal implementation + const isFirstInstall = originalConsoleError == null; + if (isFirstInstall) { + originalConsoleError = console.error.bind(console); + originalConsoleWarn = console.warn.bind(console); + + // $FlowExpectedError[cannot-write] + console.error = (...args) => { + consoleErrorImpl(...args); + }; + // $FlowExpectedError[cannot-write] + console.warn = (...args) => { + consoleWarnImpl(...args); + }; + } - warnImpl = function(...args) { - registerWarning(...args); - }; + consoleErrorImpl = registerError; + consoleWarnImpl = registerWarning; if ((console: any).disableYellowBox === true) { LogBoxData.setDisabled(true); @@ -88,6 +101,50 @@ if (__DEV__) { registerWarning(...args); }); }, + + uninstall(): void { + if (!isLogBoxInstalled) { + return; + } + + isLogBoxInstalled = false; + + // IMPORTANT: we don't re-assign to `console` in case the method has been + // decorated again after installing LogBox. E.g.: + // Before uninstalling: original > LogBox > OtherErrorHandler + // After uninstalling: original > LogBox (noop) > OtherErrorHandler + consoleErrorImpl = originalConsoleError; + consoleWarnImpl = originalConsoleWarn; + delete (console: any).disableLogBox; + }, + + isInstalled(): boolean { + return isLogBoxInstalled; + }, + + ignoreLogs(patterns: $ReadOnlyArray): void { + LogBoxData.addIgnorePatterns(patterns); + }, + + ignoreAllLogs(value?: ?boolean): void { + LogBoxData.setDisabled(value == null ? true : value); + }, + + clearAllLogs(): void { + LogBoxData.clear(); + }, + + addLog(log: LogData): void { + if (isLogBoxInstalled) { + LogBoxData.addLog(log); + } + }, + + addException(error: ExtendedExceptionData): void { + if (isLogBoxInstalled) { + LogBoxData.addException(error); + } + }, }; const isRCTLogAdviceWarning = (...args) => { @@ -103,7 +160,7 @@ if (__DEV__) { const registerWarning = (...args): void => { // Let warnings within LogBox itself fall through. if (LogBoxData.isLogBoxErrorMessage(String(args[0]))) { - error.call(console, ...args); + originalConsoleError(...args); return; } @@ -113,7 +170,7 @@ if (__DEV__) { if (!LogBoxData.isMessageIgnored(message.content)) { // Be sure to pass LogBox warnings through. - warn.call(console, ...args); + originalConsoleWarn(...args); LogBoxData.addLog({ level: 'warn', @@ -131,7 +188,7 @@ if (__DEV__) { const registerError = (...args): void => { // Let errors within LogBox itself fall through. if (LogBoxData.isLogBoxErrorMessage(args[0])) { - error.call(console, ...args); + originalConsoleError(...args); return; } @@ -144,7 +201,7 @@ if (__DEV__) { // // The 'warning' module needs to be handled here because React internally calls // `console.error('Warning: ')` with the component stack already included. - error.call(console, ...args); + originalConsoleError(...args); return; } @@ -169,7 +226,7 @@ if (__DEV__) { // Interpolate the message so they are formatted for adb and other CLIs. // This is different than the message.content above because it includes component stacks. const interpolated = parseInterpolation(args); - error.call(console, interpolated.message.content); + originalConsoleError(interpolated.message.content); LogBoxData.addLog({ level, @@ -184,28 +241,38 @@ if (__DEV__) { }; } else { LogBox = { - ignoreLogs: (patterns: $ReadOnlyArray): void => { + install(): void { + // Do nothing. + }, + + uninstall(): void { + // Do nothing. + }, + + isInstalled(): boolean { + return false; + }, + + ignoreLogs(patterns: $ReadOnlyArray): void { + // Do nothing. + }, + + ignoreAllLogs(value?: ?boolean): void { // Do nothing. }, - ignoreAllLogs: (value?: ?boolean): void => { + clearAllLogs(): void { // Do nothing. }, - install: (): void => { + addLog(log: LogData): void { // Do nothing. }, - uninstall: (): void => { + addException(error: ExtendedExceptionData): void { // Do nothing. }, }; } -module.exports = (LogBox: { - ignoreLogs($ReadOnlyArray): void, - ignoreAllLogs(?boolean): void, - install(): void, - uninstall(): void, - ... -}); +module.exports = (LogBox: ILogBox); diff --git a/Libraries/LogBox/__tests__/LogBox-test.js b/Libraries/LogBox/__tests__/LogBox-test.js index 56857f8ba29903..4c8144c7334c72 100644 --- a/Libraries/LogBox/__tests__/LogBox-test.js +++ b/Libraries/LogBox/__tests__/LogBox-test.js @@ -31,11 +31,13 @@ function mockFilterResult(returnValues) { describe('LogBox', () => { const {error, warn} = console; + let consoleError; + let consoleWarn; beforeEach(() => { jest.resetModules(); - console.error = jest.fn(); - console.warn = jest.fn(); + console.error = consoleError = jest.fn(); + console.warn = consoleWarn = jest.fn(); console.disableYellowBox = false; }); @@ -276,4 +278,107 @@ describe('LogBox', () => { }, }); }); + + it('ignores console methods after uninstalling', () => { + jest.mock('../Data/LogBoxData'); + + LogBox.install(); + LogBox.uninstall(); + + console.log('Test'); + console.warn('Test'); + console.error('Test'); + + expect(LogBoxData.addLog).not.toHaveBeenCalled(); + }); + + it('does not add logs after uninstalling', () => { + jest.mock('../Data/LogBoxData'); + + LogBox.install(); + LogBox.uninstall(); + + LogBox.addLog({ + level: 'warn', + category: 'test', + message: {content: 'Some warning', substitutions: []}, + componentStack: [], + }); + + expect(LogBoxData.addLog).not.toHaveBeenCalled(); + }); + + it('does not add exceptions after uninstalling', () => { + jest.mock('../Data/LogBoxData'); + + LogBox.install(); + LogBox.uninstall(); + + LogBox.addException({ + message: 'Some error', + originalMessage: null, + name: 'Error', + componentStack: null, + stack: [], + id: 12, + isFatal: true, + isComponentError: false, + }); + + expect(LogBoxData.addException).not.toHaveBeenCalled(); + }); + + it('preserves decorations of console.error after installing/uninstalling', () => { + LogBox.install(); + + const originalConsoleError = console.error; + console.error = message => { + originalConsoleError('Custom: ' + message); + }; + + console.error('before uninstalling'); + + expect(consoleError).toHaveBeenCalledWith('Custom: before uninstalling'); + + LogBox.uninstall(); + + console.error('after uninstalling'); + + expect(consoleError).toHaveBeenCalledWith('Custom: after uninstalling'); + + LogBox.install(); + + console.error('after installing for the second time'); + + expect(consoleError).toHaveBeenCalledWith( + 'Custom: after installing for the second time', + ); + }); + + it('preserves decorations of console.warn after installing/uninstalling', () => { + LogBox.install(); + + const originalConsoleWarn = console.warn; + console.warn = message => { + originalConsoleWarn('Custom: ' + message); + }; + + console.warn('before uninstalling'); + + expect(consoleWarn).toHaveBeenCalledWith('Custom: before uninstalling'); + + LogBox.uninstall(); + + console.warn('after uninstalling'); + + expect(consoleWarn).toHaveBeenCalledWith('Custom: after uninstalling'); + + LogBox.install(); + + console.warn('after installing for the second time'); + + expect(consoleWarn).toHaveBeenCalledWith( + 'Custom: after installing for the second time', + ); + }); }); diff --git a/Libraries/Modal/Modal.js b/Libraries/Modal/Modal.js index 353bb75c699575..7786a1e6650c5a 100644 --- a/Libraries/Modal/Modal.js +++ b/Libraries/Modal/Modal.js @@ -193,6 +193,7 @@ class Modal extends React.Component { } componentDidMount() { + // 'modalDismissed' is for the old renderer in iOS only if (ModalEventEmitter) { this._eventSubscription = ModalEventEmitter.addListener( 'modalDismissed', @@ -251,6 +252,12 @@ class Modal extends React.Component { hardwareAccelerated={this.props.hardwareAccelerated} onRequestClose={this.props.onRequestClose} onShow={this.props.onShow} + onDismiss={() => { + if (this.props.onDismiss) { + this.props.onDismiss(); + } + }} + visible={this.props.visible} statusBarTranslucent={this.props.statusBarTranslucent} identifier={this._identifier} style={styles.modal} diff --git a/Libraries/Modal/RCTModalHostViewNativeComponent.js b/Libraries/Modal/RCTModalHostViewNativeComponent.js index 53b28adeca7a2a..85f9916ef38a31 100644 --- a/Libraries/Modal/RCTModalHostViewNativeComponent.js +++ b/Libraries/Modal/RCTModalHostViewNativeComponent.js @@ -13,7 +13,6 @@ import type {HostComponent} from '../Renderer/shims/ReactNativeTypes'; import type { WithDefault, DirectEventHandler, - BubblingEventHandler, Int32, } from '../Types/CodegenTypes'; @@ -91,7 +90,14 @@ type NativeProps = $ReadOnly<{| * * See https://reactnative.dev/docs/modal.html#ondismiss */ - onDismiss?: ?BubblingEventHandler, + onDismiss?: ?DirectEventHandler, + + /** + * The `visible` prop determines whether your modal is visible. + * + * See https://reactnative.dev/docs/modal.html#visible + */ + visible?: WithDefault, /** * Deprecated. Use the `animationType` prop instead. diff --git a/Libraries/Modal/__tests__/__snapshots__/Modal-test.js.snap b/Libraries/Modal/__tests__/__snapshots__/Modal-test.js.snap index d6272a92fb5fbe..b8afa443934ab0 100644 --- a/Libraries/Modal/__tests__/__snapshots__/Modal-test.js.snap +++ b/Libraries/Modal/__tests__/__snapshots__/Modal-test.js.snap @@ -14,6 +14,7 @@ exports[` should render as when not mocked 1`] = ` animationType="none" hardwareAccelerated={false} identifier={1} + onDismiss={[Function]} onStartShouldSetResponder={[Function]} presentationStyle="fullScreen" style={ @@ -21,6 +22,7 @@ exports[` should render as when not mocked 1`] = ` "position": "absolute", } } + visible={true} > Class RCTAnimationClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"NativeAnimatedModule", RCTNativeAnimatedModuleCls}, {"NativeAnimatedTurboModule", RCTNativeAnimatedTurboModuleCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h b/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h index be7445686931bd..78325388a60d6b 100644 --- a/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h +++ b/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h @@ -15,7 +15,7 @@ @interface RCTNativeAnimatedNodesManager : NSObject -- (nonnull instancetype)initWithBridge:(nonnull RCTBridge *)bridge +- (nonnull instancetype)initWithBridge:(RCTBridge *)bridge surfacePresenter:(id)surfacePresenter; - (void)updateAnimations; diff --git a/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m b/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m index 762b44c5b40507..e7fb791193b6d2 100644 --- a/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m +++ b/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m @@ -55,7 +55,7 @@ @implementation RCTNativeAnimatedNodesManager CADisplayLink *_displayLink; } -- (instancetype)initWithBridge:(nonnull RCTBridge *)bridge surfacePresenter:(id)surfacePresenter; +- (instancetype)initWithBridge:(RCTBridge *)bridge surfacePresenter:(id)surfacePresenter; { if ((self = [super init])) { _bridge = bridge; diff --git a/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.h b/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.h index 2da04a1277eb1f..8f500132273613 100644 --- a/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.h +++ b/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.h @@ -12,12 +12,13 @@ #import #import #import +#import #import "RCTValueAnimatedNode.h" // TODO T69437152 @petetheheat - Delete this fork when Fabric ships to 100%. // NOTE: This module is temporarily forked (see RCTNativeAnimatedModule). // When making any changes, be sure to apply them to the fork as well. -@interface RCTNativeAnimatedTurboModule: RCTEventEmitter +@interface RCTNativeAnimatedTurboModule: RCTEventEmitter @end diff --git a/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.mm b/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.mm index e491139a93fe05..53208c1e0b79aa 100644 --- a/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.mm +++ b/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.mm @@ -45,6 +45,21 @@ - (instancetype)init return self; } +- (void)initialize +{ + if (self.bridge) { + _surfacePresenter = self.bridge.surfacePresenter; + _nodesManager = [[RCTNativeAnimatedNodesManager alloc] initWithBridge:self.bridge surfacePresenter:_surfacePresenter]; + [self.bridge.uiManager.observerCoordinator addObserver:self]; + } else { + // _surfacePresenter set in setSurfacePresenter: + _nodesManager = [[RCTNativeAnimatedNodesManager alloc] initWithBridge:nil surfacePresenter:_surfacePresenter]; + } + + [_surfacePresenter addObserver:self]; + [[self.moduleRegistry moduleForName:"EventDispatcher"] addDispatchObserver:self]; +} + - (void)invalidate { [super invalidate]; @@ -62,21 +77,6 @@ - (dispatch_queue_t)methodQueue return RCTGetUIManagerQueue(); } -- (void)setBridge:(RCTBridge *)bridge -{ - [super setBridge:bridge]; - _surfacePresenter = bridge.surfacePresenter; - _nodesManager = [[RCTNativeAnimatedNodesManager alloc] initWithBridge:self.bridge surfacePresenter:_surfacePresenter]; - [bridge.uiManager.observerCoordinator addObserver:self]; - [_surfacePresenter addObserver:self]; -} - -- (void)setModuleRegistry:(RCTModuleRegistry *)moduleRegistry -{ - [super setModuleRegistry:moduleRegistry]; - [[moduleRegistry moduleForName:"EventDispatcher"] addDispatchObserver:self]; -} - /* * In bridgeless mode, `setBridge` is never called during initializtion. Instead this selector is invoked via * BridgelessTurboModuleSetup. @@ -84,8 +84,6 @@ - (void)setModuleRegistry:(RCTModuleRegistry *)moduleRegistry - (void)setSurfacePresenter:(id)surfacePresenter { _surfacePresenter = surfacePresenter; - _nodesManager = [[RCTNativeAnimatedNodesManager alloc] initWithBridge:self.bridge surfacePresenter:_surfacePresenter]; - [_surfacePresenter addObserver:self]; } #pragma mark -- API diff --git a/Libraries/NativeAnimation/React-RCTAnimation.podspec b/Libraries/NativeAnimation/React-RCTAnimation.podspec index 79512b27dff21d..5191a15cb7f94e 100644 --- a/Libraries/NativeAnimation/React-RCTAnimation.podspec +++ b/Libraries/NativeAnimation/React-RCTAnimation.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTAnimation" diff --git a/Libraries/Network/RCTNetworkPlugins.mm b/Libraries/Network/RCTNetworkPlugins.mm index 6a00252c5679b8..f1a016e1d209c8 100644 --- a/Libraries/Network/RCTNetworkPlugins.mm +++ b/Libraries/Network/RCTNetworkPlugins.mm @@ -17,15 +17,16 @@ #import Class RCTNetworkClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"Networking", RCTNetworkingCls}, {"DataRequestHandler", RCTDataRequestHandlerCls}, {"FileRequestHandler", RCTFileRequestHandlerCls}, {"HTTPRequestHandler", RCTHTTPRequestHandlerCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/Libraries/Network/RCTNetworking.h b/Libraries/Network/RCTNetworking.h index 18344302ea8034..2068f32b803038 100644 --- a/Libraries/Network/RCTNetworking.h +++ b/Libraries/Network/RCTNetworking.h @@ -31,7 +31,7 @@ * Allows RCTNetworking instances to be initialized with handlers. * The handlers will be requested via the bridge's moduleForName method when required. */ -- (instancetype)initWithHandlersProvider:(NSArray> * (^)(void))getHandlers; +- (instancetype)initWithHandlersProvider:(NSArray> * (^)(RCTModuleRegistry *))getHandlers; /** * Does a handler exist for the specified request? diff --git a/Libraries/Network/RCTNetworking.mm b/Libraries/Network/RCTNetworking.mm index 0f9c3d61c0b104..22ca45b0fa3ff4 100644 --- a/Libraries/Network/RCTNetworking.mm +++ b/Libraries/Network/RCTNetworking.mm @@ -148,7 +148,7 @@ @implementation RCTNetworking NSMutableDictionary *_tasksByRequestID; std::mutex _handlersLock; NSArray> *_handlers; - NSArray> * (^_handlersProvider)(void); + NSArray> * (^_handlersProvider)(RCTModuleRegistry *); NSMutableArray> *_requestHandlers; NSMutableArray> *_responseHandlers; } @@ -167,7 +167,7 @@ - (instancetype)init return [super initWithDisabledObservation]; } -- (instancetype)initWithHandlersProvider:(NSArray> * (^)(void))getHandlers +- (instancetype)initWithHandlersProvider:(NSArray> * (^)(RCTModuleRegistry *moduleRegistry))getHandlers { if (self = [super initWithDisabledObservation]) { _handlersProvider = getHandlers; @@ -209,7 +209,7 @@ - (void)invalidate if (!_handlers) { if (_handlersProvider) { - _handlers = _handlersProvider(); + _handlers = _handlersProvider(self.moduleRegistry); } else { _handlers = [self.bridge modulesConformingToProtocol:@protocol(RCTURLRequestHandler)]; } diff --git a/Libraries/Network/React-RCTNetwork.podspec b/Libraries/Network/React-RCTNetwork.podspec index fd3ec2b606cea6..602d3670051e3a 100644 --- a/Libraries/Network/React-RCTNetwork.podspec +++ b/Libraries/Network/React-RCTNetwork.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTNetwork" diff --git a/Libraries/NewAppScreen/components/HermesBadge.js b/Libraries/NewAppScreen/components/HermesBadge.js index aa02f3a9881455..b0907266e02406 100644 --- a/Libraries/NewAppScreen/components/HermesBadge.js +++ b/Libraries/NewAppScreen/components/HermesBadge.js @@ -15,6 +15,9 @@ import Colors from './Colors'; const HermesBadge = (): Node => { const isDarkMode = useColorScheme() === 'dark'; + const version = + global.HermesInternal?.getRuntimeProperties?.()['OSS Release Version'] ?? + ''; return global.HermesInternal ? ( { color: isDarkMode ? Colors.light : Colors.dark, }, ]}> - Engine: Hermes + {`Engine: Hermes ${version}`} ) : null; diff --git a/Libraries/PermissionsAndroid/NativePermissionsAndroid.js b/Libraries/PermissionsAndroid/NativePermissionsAndroid.js index 66596f9e97d3b1..64d55e5f334264 100644 --- a/Libraries/PermissionsAndroid/NativePermissionsAndroid.js +++ b/Libraries/PermissionsAndroid/NativePermissionsAndroid.js @@ -41,7 +41,9 @@ export type PermissionType = | 'android.permission.RECEIVE_WAP_PUSH' | 'android.permission.RECEIVE_MMS' | 'android.permission.READ_EXTERNAL_STORAGE' - | 'android.permission.WRITE_EXTERNAL_STORAGE'; + | 'android.permission.WRITE_EXTERNAL_STORAGE' + | 'android.permission.BLUETOOTH_CONNECT' + | 'android.permission.BLUETOOTH_SCAN'; */ export interface Spec extends TurboModule { diff --git a/Libraries/PermissionsAndroid/PermissionsAndroid.js b/Libraries/PermissionsAndroid/PermissionsAndroid.js index 146c457070d31a..c538dfd803549b 100644 --- a/Libraries/PermissionsAndroid/PermissionsAndroid.js +++ b/Libraries/PermissionsAndroid/PermissionsAndroid.js @@ -59,6 +59,8 @@ const PERMISSIONS = Object.freeze({ RECEIVE_MMS: 'android.permission.RECEIVE_MMS', READ_EXTERNAL_STORAGE: 'android.permission.READ_EXTERNAL_STORAGE', WRITE_EXTERNAL_STORAGE: 'android.permission.WRITE_EXTERNAL_STORAGE', + BLUETOOTH_CONNECT: 'android.permission.BLUETOOTH_CONNECT', + BLUETOOTH_SCAN: 'android.permission.BLUETOOTH_SCAN', }); /** @@ -73,6 +75,8 @@ class PermissionsAndroid { ACCESS_COARSE_LOCATION: string, ACCESS_FINE_LOCATION: string, ADD_VOICEMAIL: string, + BLUETOOTH_CONNECT: string, + BLUETOOTH_SCAN: string, BODY_SENSORS: string, CALL_PHONE: string, CAMERA: string, diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm b/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm index 587a7b17a86688..434829371738ec 100644 --- a/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm +++ b/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm @@ -17,12 +17,13 @@ #import Class RCTPushNotificationClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"PushNotificationManager", RCTPushNotificationManagerCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec b/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec index da8e5a29e6e0a1..4c2232d044046e 100644 --- a/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec +++ b/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTPushNotification" diff --git a/Libraries/RCTRequired/BUCK b/Libraries/RCTRequired/BUCK index 18d34dc7750d91..53eb8a475d3ba7 100644 --- a/Libraries/RCTRequired/BUCK +++ b/Libraries/RCTRequired/BUCK @@ -2,7 +2,10 @@ load("//tools/build_defs/oss:rn_defs.bzl", "fb_apple_library") fb_apple_library( name = "RCTRequired", - autoglob = True, + exported_headers = [ + "RCTRequired/RCTRequired.h", + ], + autoglob = False, complete_nullability = True, contacts = ["oncall+react_native@xmail.facebook.com"], extension_api_only = True, diff --git a/Libraries/ReactNative/AppContainer.js b/Libraries/ReactNative/AppContainer.js index 7740178689de09..2024b4cee44b35 100644 --- a/Libraries/ReactNative/AppContainer.js +++ b/Libraries/ReactNative/AppContainer.js @@ -13,12 +13,13 @@ import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter'; import StyleSheet from '../StyleSheet/StyleSheet'; import {type EventSubscription} from '../vendor/emitter/EventEmitter'; import {RootTagContext, createRootTag} from './RootTag'; +import type {RootTag} from './RootTag'; import * as React from 'react'; type Props = $ReadOnly<{| children?: React.Node, fabric?: boolean, - rootTag: number, + rootTag: number | RootTag, initialProps?: {...}, showArchitectureIndicator?: boolean, WrapperComponent?: ?React.ComponentType, @@ -130,11 +131,4 @@ const styles = StyleSheet.create({ }, }); -if (__DEV__) { - if (!global.__RCTProfileIsProfiling) { - const LogBox = require('../LogBox/LogBox'); - LogBox.install(); - } -} - module.exports = AppContainer; diff --git a/Libraries/ReactNative/AppRegistry.js b/Libraries/ReactNative/AppRegistry.js index 96edccc10963f1..0bb8a8658f7ef0 100644 --- a/Libraries/ReactNative/AppRegistry.js +++ b/Libraries/ReactNative/AppRegistry.js @@ -22,6 +22,7 @@ import {coerceDisplayMode} from './DisplayMode'; import createPerformanceLogger from '../Utilities/createPerformanceLogger'; import NativeHeadlessJsTaskSupport from './NativeHeadlessJsTaskSupport'; import HeadlessJsTaskError from './HeadlessJsTaskError'; +import type {RootTag} from 'react-native/Libraries/Types/RootTagTypes'; type Task = (taskData: any) => Promise; export type TaskProvider = () => Task; @@ -243,7 +244,9 @@ const AppRegistry = { * * See https://reactnative.dev/docs/appregistry.html#unmountapplicationcomponentatroottag */ - unmountApplicationComponentAtRootTag(rootTag: number): void { + unmountApplicationComponentAtRootTag(rootTag: RootTag): void { + // NOTE: RootTag type + // $FlowFixMe[incompatible-call] RootTag: RootTag is incompatible with number, needs an updated synced version of the ReactNativeTypes.js file ReactNative.unmountComponentAtNodeAndRemoveContainer(rootTag); }, diff --git a/Libraries/ReactNative/DisplayMode.js b/Libraries/ReactNative/DisplayMode.js index 30e76fcccd7051..e6850f0eb4ca0b 100644 --- a/Libraries/ReactNative/DisplayMode.js +++ b/Libraries/ReactNative/DisplayMode.js @@ -19,15 +19,14 @@ const DisplayMode: {[string]: DisplayModeType} = Object.freeze({ }); export function coerceDisplayMode(value: ?number): DisplayModeType { - if (value == null || value === undefined) { - return DisplayMode.VISIBLE; - } switch (value) { case DisplayMode.SUSPENDED: + return DisplayMode.SUSPENDED; case DisplayMode.HIDDEN: - return value; + return DisplayMode.HIDDEN; + default: + return DisplayMode.VISIBLE; } - return DisplayMode.VISIBLE; } export default DisplayMode; diff --git a/Libraries/ReactNative/DummyUIManager.js b/Libraries/ReactNative/DummyUIManager.js index 0d380f0a276f86..bdf874592613a8 100644 --- a/Libraries/ReactNative/DummyUIManager.js +++ b/Libraries/ReactNative/DummyUIManager.js @@ -10,6 +10,8 @@ 'use strict'; +import type {RootTag} from 'react-native/Libraries/Types/RootTagTypes'; + module.exports = { getViewManagerConfig: (viewManagerName: string): mixed => { console.warn( @@ -21,7 +23,10 @@ module.exports = { return null; }, hasViewManagerConfig: (viewManagerName: string): boolean => { - return viewManagerName === 'RCTVirtualText'; + return ( + viewManagerName === 'RCTVirtualText' || + viewManagerName === 'RCTShimmeringView' + ); }, getConstants: (): {...} => ({}), getConstantsForViewManager: (viewManagerName: string) => {}, @@ -30,7 +35,7 @@ module.exports = { createView: ( reactTag: ?number, viewName: string, - rootTag: number, + rootTag: RootTag, props: Object, ) => {}, updateView: (reactTag: number, viewName: string, props: Object) => {}, diff --git a/Libraries/ReactNative/FabricUIManager.js b/Libraries/ReactNative/FabricUIManager.js index 62c17e8e4ad996..987ef84f3812da 100644 --- a/Libraries/ReactNative/FabricUIManager.js +++ b/Libraries/ReactNative/FabricUIManager.js @@ -16,6 +16,7 @@ import type { MeasureLayoutOnSuccessCallback, LayoutAnimationConfig, } from '../Renderer/shims/ReactNativeTypes'; +import type {RootTag} from 'react-native/Libraries/Types/RootTagTypes'; // TODO: type these properly. type Node = {...}; @@ -26,7 +27,7 @@ export type Spec = {| +createNode: ( reactTag: number, viewName: string, - rootTag: number, + rootTag: RootTag, props: NodeProps, instanceHandle: InstanceHandle, ) => Node, @@ -34,10 +35,10 @@ export type Spec = {| +cloneNodeWithNewChildren: (node: Node) => Node, +cloneNodeWithNewProps: (node: Node, newProps: NodeProps) => Node, +cloneNodeWithNewChildrenAndProps: (node: Node, newProps: NodeProps) => Node, - +createChildSet: (rootTag: number) => NodeSet, + +createChildSet: (rootTag: RootTag) => NodeSet, +appendChild: (parentNode: Node, child: Node) => Node, +appendChildToSet: (childSet: NodeSet, child: Node) => void, - +completeRoot: (rootTag: number, childSet: NodeSet) => void, + +completeRoot: (rootTag: RootTag, childSet: NodeSet) => void, +measure: (node: Node, callback: MeasureOnSuccessCallback) => void, +measureInWindow: ( node: Node, diff --git a/Libraries/ReactNative/I18nManager.js b/Libraries/ReactNative/I18nManager.js index 9fa21e78dacc22..1095ab81cdb3ee 100644 --- a/Libraries/ReactNative/I18nManager.js +++ b/Libraries/ReactNative/I18nManager.js @@ -13,12 +13,17 @@ import NativeI18nManager from './NativeI18nManager'; const i18nConstants: {| doLeftAndRightSwapInRTL: boolean, isRTL: boolean, + localeIdentifier?: ?string, |} = getI18nManagerConstants(); function getI18nManagerConstants() { if (NativeI18nManager) { - const {isRTL, doLeftAndRightSwapInRTL} = NativeI18nManager.getConstants(); - return {isRTL, doLeftAndRightSwapInRTL}; + const { + isRTL, + doLeftAndRightSwapInRTL, + localeIdentifier, + } = NativeI18nManager.getConstants(); + return {isRTL, doLeftAndRightSwapInRTL, localeIdentifier}; } return { @@ -28,7 +33,11 @@ function getI18nManagerConstants() { } module.exports = { - getConstants: (): {|doLeftAndRightSwapInRTL: boolean, isRTL: boolean|} => { + getConstants: (): {| + doLeftAndRightSwapInRTL: boolean, + isRTL: boolean, + localeIdentifier: ?string, + |} => { return i18nConstants; }, diff --git a/Libraries/ReactNative/NativeUIManager.js b/Libraries/ReactNative/NativeUIManager.js index 53fa251eed93d5..ce77d2d4db341d 100644 --- a/Libraries/ReactNative/NativeUIManager.js +++ b/Libraries/ReactNative/NativeUIManager.js @@ -8,6 +8,7 @@ * @format */ +import type {RootTag} from '../TurboModule/RCTExport'; import type {TurboModule} from '../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; @@ -19,7 +20,7 @@ export interface Spec extends TurboModule { +createView: ( reactTag: ?number, viewName: string, - rootTag: number, + rootTag: RootTag, props: Object, ) => void; +updateView: (reactTag: number, viewName: string, props: Object) => void; diff --git a/Libraries/ReactNative/PaperUIManager.js b/Libraries/ReactNative/PaperUIManager.js index fe9cc014cc6e01..c468958e566320 100644 --- a/Libraries/ReactNative/PaperUIManager.js +++ b/Libraries/ReactNative/PaperUIManager.js @@ -15,6 +15,7 @@ const UIManagerProperties = require('./UIManagerProperties'); const defineLazyObjectProperty = require('../Utilities/defineLazyObjectProperty'); import NativeUIManager from './NativeUIManager'; +import type {RootTag} from 'react-native/Libraries/Types/RootTagTypes'; const viewManagerConfigs = {}; @@ -84,7 +85,7 @@ const UIManagerJS = { createView( reactTag: ?number, viewName: string, - rootTag: number, + rootTag: RootTag, props: Object, ): void { if (Platform.OS === 'ios' && viewManagerConfigs[viewName] === undefined) { diff --git a/Libraries/ReactNative/RootTag.js b/Libraries/ReactNative/RootTag.js index 0470e42487e322..03c83a86af9713 100644 --- a/Libraries/ReactNative/RootTag.js +++ b/Libraries/ReactNative/RootTag.js @@ -11,7 +11,7 @@ import * as React from 'react'; // TODO: Make this into an opaque type. -export type RootTag = number; +export opaque type RootTag = number; export const RootTagContext: React$Context = React.createContext( 0, @@ -24,6 +24,6 @@ if (__DEV__) { /** * Intended to only be used by `AppContainer`. */ -export function createRootTag(rootTag: number): RootTag { +export function createRootTag(rootTag: number | RootTag): RootTag { return rootTag; } diff --git a/Libraries/ReactNative/UIManager.js b/Libraries/ReactNative/UIManager.js index 668961338d2d10..ac916e66a2410b 100644 --- a/Libraries/ReactNative/UIManager.js +++ b/Libraries/ReactNative/UIManager.js @@ -10,6 +10,7 @@ import UIManagerInjection from './UIManagerInjection'; import type {Spec} from './NativeUIManager'; +import type {RootTag} from 'react-native/Libraries/Types/RootTagTypes'; interface UIManagerJSInterface extends Spec { +getViewManagerConfig: (viewManagerName: string) => Object; @@ -17,7 +18,7 @@ interface UIManagerJSInterface extends Spec { +createView: ( reactTag: ?number, viewName: string, - rootTag: number, + rootTag: RootTag, props: Object, ) => void; +updateView: (reactTag: number, viewName: string, props: Object) => void; diff --git a/Libraries/ReactNative/getCachedComponentWithDebugName.js b/Libraries/ReactNative/getCachedComponentWithDebugName.js new file mode 100644 index 00000000000000..7e5e116399adf7 --- /dev/null +++ b/Libraries/ReactNative/getCachedComponentWithDebugName.js @@ -0,0 +1,32 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +import type {AbstractComponent, Node} from 'react'; + +type NoopComponent = AbstractComponent<{children: Node}>; + +const cache: Map< + string, // displayName + NoopComponent, // ComponentWithDisplayName +> = new Map(); + +export default function getCachedComponentWithDisplayName( + displayName: string, +): NoopComponent { + let ComponentWithDisplayName = cache.get(displayName); + + if (!ComponentWithDisplayName) { + ComponentWithDisplayName = ({children}) => children; + ComponentWithDisplayName.displayName = displayName; + cache.set(displayName, ComponentWithDisplayName); + } + + return ComponentWithDisplayName; +} diff --git a/Libraries/ReactNative/renderApplication.js b/Libraries/ReactNative/renderApplication.js index 8c916978380a92..5278769cd3fd71 100644 --- a/Libraries/ReactNative/renderApplication.js +++ b/Libraries/ReactNative/renderApplication.js @@ -13,6 +13,7 @@ import GlobalPerformanceLogger from '../Utilities/GlobalPerformanceLogger'; import type {IPerformanceLogger} from '../Utilities/createPerformanceLogger'; import PerformanceLoggerContext from '../Utilities/PerformanceLoggerContext'; import type {DisplayModeType} from './DisplayMode'; +import getCachedComponentWithDebugName from './getCachedComponentWithDebugName'; const React = require('react'); const invariant = require('invariant'); @@ -51,8 +52,9 @@ function renderApplication( ); if (__DEV__ && debugName) { - const RootComponentWithMeaningfulName = ({children}) => children; - RootComponentWithMeaningfulName.displayName = `${debugName}(RootComponent)`; + const RootComponentWithMeaningfulName = getCachedComponentWithDebugName( + `${debugName}(RootComponent)`, + ); renderable = ( {renderable} diff --git a/Libraries/ReactPrivate/ReactNativePrivateInterface.js b/Libraries/ReactPrivate/ReactNativePrivateInterface.js index e182380e6140ff..82c1896ad9b8a5 100644 --- a/Libraries/ReactPrivate/ReactNativePrivateInterface.js +++ b/Libraries/ReactPrivate/ReactNativePrivateInterface.js @@ -58,7 +58,7 @@ module.exports = { return require('../StyleSheet/flattenStyle'); }, get ReactFiberErrorDialog(): ReactFiberErrorDialog { - return require('../Core/ReactFiberErrorDialog'); + return require('../Core/ReactFiberErrorDialog').default; }, get legacySendAccessibilityEvent(): legacySendAccessibilityEvent { return require('../Components/AccessibilityInfo/legacySendAccessibilityEvent'); diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index 35a6ff2d75f5a7..be9f717f7f4e83 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -c9aab1c9d00ce407b1c61c385b356d49cd147f60 \ No newline at end of file +2d8d133e1756ea50a48e615db0c22870e92f4af6 \ 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 177533bae2082b..d43ff6ad0019ab 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<7d94bdf10150fe93a2e9fa8bbf998840>> + * @generated SignedSource<<3836d5af681381d070c07bf87c303843>> */ 'use strict'; @@ -20,7 +20,6 @@ var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); var Scheduler = require("scheduler"); -var tracing = require("scheduler/tracing"); var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; @@ -380,6 +379,12 @@ function clearCaughtError() { } } +var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare + +function isArray(a) { + return isArrayImpl(a); +} + var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -407,13 +412,13 @@ var validateEventDispatches; validateEventDispatches = function(event) { var dispatchListeners = event._dispatchListeners; var dispatchInstances = event._dispatchInstances; - var listenersIsArr = Array.isArray(dispatchListeners); + var listenersIsArr = isArray(dispatchListeners); var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; - var instancesIsArr = Array.isArray(dispatchInstances); + var instancesIsArr = isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances @@ -450,7 +455,7 @@ function executeDispatchesInOrder(event) { validateEventDispatches(event); } - if (Array.isArray(dispatchListeners)) { + if (isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; @@ -481,7 +486,7 @@ function executeDispatchesInOrderStopAtTrueImpl(event) { validateEventDispatches(event); } - if (Array.isArray(dispatchListeners)) { + if (isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; @@ -527,7 +532,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners; var dispatchInstance = event._dispatchInstances; - if (!!Array.isArray(dispatchListener)) { + if (!!isArray(dispatchListener)) { throw Error("executeDirectDispatch(...): Invalid `event`."); } @@ -1154,11 +1159,11 @@ function accumulate(current, next) { } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { + if (isArray(current)) { return current.concat(next); } - if (Array.isArray(next)) { + if (isArray(next)) { return [current].concat(next); } @@ -1190,8 +1195,8 @@ function accumulateInto(current, next) { } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { - if (Array.isArray(next)) { + if (isArray(current)) { + if (isArray(next)) { current.push.apply(current, next); return current; } @@ -1200,7 +1205,7 @@ function accumulateInto(current, next) { return current; } - if (Array.isArray(next)) { + if (isArray(next)) { // A bit too dangerous to mutate `next`. return [current].concat(next); } @@ -2505,10 +2510,30 @@ function getFiberCurrentPropsFromNode$1(inst) { var ReactFabricGlobalResponderHandler = { onChange: function(from, to, blockNativeResponder) { var fromOrTo = from || to; - var isFabric = !!fromOrTo.stateNode.canonical._internalInstanceHandle; + var fromOrToStateNode = fromOrTo && fromOrTo.stateNode; + var isFabric = !!( + fromOrToStateNode && fromOrToStateNode.canonical._internalInstanceHandle + ); - if (isFabric); - else { + if (isFabric) { + if (from) { + // equivalent to clearJSResponder + nativeFabricUIManager.setIsJSResponder( + from.stateNode.node, + false, + blockNativeResponder || false + ); + } + + if (to) { + // equivalent to setJSResponder + nativeFabricUIManager.setIsJSResponder( + to.stateNode.node, + true, + blockNativeResponder || false + ); + } + } else { if (to !== null) { var tag = to.stateNode.canonical._nativeTag; ReactNativePrivateInterface.UIManager.setJSResponder( @@ -2612,11 +2637,16 @@ function getIteratorFn(maybeIterable) { } function getWrappedName(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + + if (displayName) { + return displayName; + } + var functionName = innerType.displayName || innerType.name || ""; - return ( - outerType.displayName || - (functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName) - ); + return functionName !== "" + ? wrapperName + "(" + functionName + ")" + : wrapperName; } // Keep in sync with react-reconciler/getComponentNameFromFiber function getContextName(type) { @@ -2632,7 +2662,7 @@ function getComponentNameFromType(type) { { if (typeof type.tag === "number") { error( - "Received an unexpected object in getComponentName(). " + + "Received an unexpected object in getComponentNameFromType(). " + "This is likely a bug in React. Please file an issue." ); } @@ -2683,7 +2713,13 @@ function getComponentNameFromType(type) { return getWrappedName(type, type.render, "ForwardRef"); case REACT_MEMO_TYPE: - return getComponentNameFromType(type.type); + var outerName = type.displayName || null; + + if (outerName !== null) { + return outerName; + } + + return getComponentNameFromType(type.type) || "Memo"; case REACT_LAZY_TYPE: { var lazyComponent = type; @@ -2809,7 +2845,7 @@ var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; var deferRenderPhaseUpdateToNextBatch = true; -var enableLazyContextPropagation = false; // Flow magic to verify the exports of this file match the original version. +var enableLazyContextPropagation = false; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -2878,9 +2914,24 @@ var ForceUpdateForLegacySuspense = // since we can defer traversing the tree during layout to look for Passive effects, // and instead rely on the static flag as a signal that there may be cleanup work. +var RefStatic = + /* */ + 262144; +var LayoutStatic = + /* */ + 524288; var PassiveStatic = /* */ - 262144; // These flags allow us to traverse to fibers that have effects on mount + 1048576; // These flags allow us to traverse to fibers that have effects on mount +// without traversing the entire tree after every commit for +// double invoking + +var MountLayoutDev = + /* */ + 2097152; +var MountPassiveDev = + /* */ + 4194304; // Groups of flags that are used in the commit phase to skip over trees that // don't contain effects, by checking subtreeFlags. var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity @@ -2900,7 +2951,7 @@ var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset // This allows certain concepts to persist without recalculting them, // e.g. whether a subtree contains passive effects or portals. -var StaticMask = PassiveStatic; +var StaticMask = LayoutStatic | PassiveStatic | RefStatic; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -3248,7 +3299,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) { + if (isArray(node)) { var i = node.length; while (i-- && removedKeyCount > 0) { @@ -3373,12 +3424,12 @@ function diffNestedProperty( return updatePayload; } - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) { + if (!isArray(prevProp) && !isArray(nextProp)) { // Both are leaves, we can diff the leaves. return diffProperties(updatePayload, prevProp, nextProp, validAttributes); } - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArray(prevProp) && isArray(nextProp)) { // Both are arrays, we can diff the arrays. return diffNestedArrayProperty( updatePayload, @@ -3388,7 +3439,7 @@ function diffNestedProperty( ); } - if (Array.isArray(prevProp)) { + if (isArray(prevProp)) { return diffProperties( updatePayload, // $FlowFixMe - We know that this is always an object when the input is. ReactNativePrivateInterface.flattenStyle(prevProp), // $FlowFixMe - We know that this isn't an array because of above flow. @@ -3415,7 +3466,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { return updatePayload; } - if (!Array.isArray(nextProp)) { + if (!isArray(nextProp)) { // Add each property of the leaf. return addProperties(updatePayload, nextProp, validAttributes); } @@ -3441,7 +3492,7 @@ function clearNestedProperty(updatePayload, prevProp, validAttributes) { return updatePayload; } - if (!Array.isArray(prevProp)) { + if (!isArray(prevProp)) { // Add each property of the leaf. return clearProperties(updatePayload, prevProp, validAttributes); } @@ -3696,7 +3747,6 @@ function batchedUpdates(fn, bookkeeping) { function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, - _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; @@ -3830,6 +3880,186 @@ function dispatchEvent(target, topLevelType, nativeEvent) { // where it would do it. } +// This module only exists as an ESM wrapper around the external CommonJS +var scheduleCallback = Scheduler.unstable_scheduleCallback; +var cancelCallback = Scheduler.unstable_cancelCallback; +var shouldYield = Scheduler.unstable_shouldYield; +var requestPaint = Scheduler.unstable_requestPaint; +var now = Scheduler.unstable_now; +var ImmediatePriority = Scheduler.unstable_ImmediatePriority; +var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var NormalPriority = Scheduler.unstable_NormalPriority; +var IdlePriority = Scheduler.unstable_IdlePriority; + +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; + } + + 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) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. + + return true; + } + + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists + + return true; +} +function onScheduleRoot(root, children) { + { + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { + try { + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onCommitRoot(root, eventPriority) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; + + if (enableProfilerTimer) { + var schedulerPriority; + + switch (eventPriority) { + case DiscreteEventPriority: + schedulerPriority = ImmediatePriority; + break; + + case ContinuousEventPriority: + schedulerPriority = UserBlockingPriority; + break; + + case DefaultEventPriority: + schedulerPriority = NormalPriority; + break; + + case IdleEventPriority: + schedulerPriority = IdlePriority; + break; + + default: + schedulerPriority = NormalPriority; + break; + } + + injectedHook.onCommitFiberRoot( + rendererID, + root, + schedulerPriority, + didError + ); + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onPostCommitRoot(root) { + if ( + injectedHook && + typeof injectedHook.onPostCommitFiberRoot === "function" + ) { + try { + injectedHook.onPostCommitFiberRoot(rendererID, root); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} + +var NoMode = + /* */ + 0; // TODO: Remove ConcurrentMode by reading from the root tag instead + +var ConcurrentMode = + /* */ + 1; +var ProfileMode = + /* */ + 2; +var DebugTracingMode = + /* */ + 4; +var StrictLegacyMode = + /* */ + 8; +var StrictEffectsMode = + /* */ + 16; +var ConcurrentUpdatesByDefaultMode = + /* */ + 32; + // If those values are changed that package should be rebuilt and redeployed. var TotalLanes = 31; @@ -3843,7 +4073,7 @@ var SyncLane = /* */ 1; var InputContinuousHydrationLane = - /* */ + /* */ 2; var InputContinuousLane = /* */ @@ -4080,6 +4310,15 @@ function getNextLanes(root, wipLanes) { // Keep working on the existing in-progress tree. Do not interrupt. return wipLanes; } + } + + if ((root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode); + else if ((nextLanes & InputContinuousLane) !== NoLanes) { + // When updates are sync by default, we entangle continuous priority updates + // and default updates, so they render in the same batch. The only reason + // they use separate lanes is because continuous updates should interrupt + // transitions, but default updates should not. + nextLanes |= pendingLanes & DefaultLane; } // Check for entangled lanes and add them to the batch. // // A lane is said to be entangled with another when it's not allowed to render @@ -4173,12 +4412,19 @@ function computeExpirationTime(lane, currentTime) { case TransitionLane14: case TransitionLane15: case TransitionLane16: + return currentTime + 5000; + case RetryLane1: case RetryLane2: case RetryLane3: case RetryLane4: case RetryLane5: - return currentTime + 5000; + // TODO: Retries should be allowed to expire if they are CPU bound for + // too long, but when I made this change it caused a spike in browser + // crashes. There must be some other underlying bug; not super urgent but + // ideally should figure out why and fix it. Unfortunately we don't have + // a repro for the crashes, only detected via production metrics. + return NoTimestamp; case SelectiveHydrationLane: case IdleHydrationLane: @@ -4208,7 +4454,6 @@ function markStarvedLanesAsExpired(root, currentTime) { // it as expired to force it to finish. var lanes = pendingLanes; - var expiredLanes = 0; while (lanes > 0) { var index = pickArbitraryLaneIndex(lanes); @@ -4228,15 +4473,11 @@ function markStarvedLanesAsExpired(root, currentTime) { } } else if (expirationTime <= currentTime) { // This lane expired - expiredLanes |= lane; + root.expiredLanes |= lane; } lanes &= ~lane; } - - if (expiredLanes !== 0) { - markRootExpired(root, expiredLanes); - } } // This returns the highest priority pending lanes regardless of whether they function getLanesToRetrySynchronouslyOnError(root) { var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; @@ -4260,6 +4501,25 @@ function includesOnlyRetries(lanes) { function includesOnlyTransitions(lanes) { return (lanes & TransitionLanes) === lanes; } +function shouldTimeSlice(root, lanes) { + if ((lanes & root.expiredLanes) !== NoLanes) { + // At least one of these lanes expired. To prevent additional starvation, + // finish rendering without yielding execution. + return false; + } + + if ((root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode) { + // Concurrent updates by default always use time slicing. + return true; + } + + var SyncDefaultLanes = + InputContinuousHydrationLane | + InputContinuousLane | + DefaultHydrationLane | + DefaultLane; + return (lanes & SyncDefaultLanes) === NoLanes; +} function isTransitionLane(lane) { return (lane & TransitionLanes) !== 0; } @@ -4378,18 +4638,6 @@ function markRootSuspended(root, suspendedLanes) { function markRootPinged(root, pingedLanes, eventTime) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } -function markRootExpired(root, expiredLanes) { - var entanglements = root.entanglements; - var SyncLaneIndex = 0; - entanglements[SyncLaneIndex] |= expiredLanes; - root.entangledLanes |= SyncLane; - root.pendingLanes |= SyncLane; -} -function areLanesExpired(root, lanes) { - var SyncLaneIndex = 0; - var entanglements = root.entanglements; - return (entanglements[SyncLaneIndex] & lanes) !== NoLanes; -} function markRootMutableRead(root, updateLane) { root.mutableReadLanes |= updateLane & root.pendingLanes; } @@ -4399,6 +4647,7 @@ function markRootFinished(root, remainingLanes) { root.suspendedLanes = 0; root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; root.mutableReadLanes &= remainingLanes; root.entangledLanes &= remainingLanes; @@ -4477,6 +4726,9 @@ function setCurrentUpdatePriority(newPriority) { function higherEventPriority(a, b) { return a !== 0 && a < b ? a : b; } +function lowerEventPriority(a, b) { + return a === 0 || a > b ? a : b; +} function isHigherEventPriority(a, b) { return a !== 0 && a < b; } @@ -5052,6 +5304,8 @@ function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { return ""; } +var hasOwnProperty = Object.prototype.hasOwnProperty; + var loggedTypeFailures = {}; var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; @@ -5074,7 +5328,7 @@ function setCurrentlyValidatingElement(element) { function checkPropTypes(typeSpecs, values, location, componentName, element) { { // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); + var has = Function.call.bind(hasOwnProperty); for (var typeSpecName in typeSpecs) { if (has(typeSpecs, typeSpecName)) { @@ -5474,175 +5728,35 @@ function findCurrentUnmaskedContext(fiber) { var LegacyRoot = 0; var ConcurrentRoot = 1; -// This module only exists as an ESM wrapper around the external CommonJS -var scheduleCallback = Scheduler.unstable_scheduleCallback; -var cancelCallback = Scheduler.unstable_cancelCallback; -var shouldYield = Scheduler.unstable_shouldYield; -var requestPaint = Scheduler.unstable_requestPaint; -var now = Scheduler.unstable_now; -var ImmediatePriority = Scheduler.unstable_ImmediatePriority; -var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; -var NormalPriority = Scheduler.unstable_NormalPriority; -var IdlePriority = Scheduler.unstable_IdlePriority; - -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); +var syncQueue = null; +var includesLegacySyncCallbacks = false; +var isFlushingSyncQueue = false; +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]; + } else { + // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); } } - -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; - } - - 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) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. - - return true; - } - - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists - - return true; -} -function onScheduleRoot(root, children) { - { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } -} -function onCommitRoot(root, eventPriority) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; - - if (enableProfilerTimer) { - var schedulerPriority; - - switch (eventPriority) { - case DiscreteEventPriority: - schedulerPriority = ImmediatePriority; - break; - - case ContinuousEventPriority: - schedulerPriority = UserBlockingPriority; - break; - - case DefaultEventPriority: - schedulerPriority = NormalPriority; - break; - - case IdleEventPriority: - schedulerPriority = IdlePriority; - break; - - default: - schedulerPriority = NormalPriority; - break; - } - - injectedHook.onCommitFiberRoot( - rendererID, - root, - schedulerPriority, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } -} -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } +function scheduleLegacySyncCallback(callback) { + includesLegacySyncCallbacks = true; + scheduleSyncCallback(callback); } - -var syncQueue = null; -var isFlushingSyncQueue = false; -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]; - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - syncQueue.push(callback); +function flushSyncCallbacksOnlyInLegacyMode() { + // Only flushes the queue if there's a legacy sync callback scheduled. + // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So + // it might make more sense for the queue to be a list of roots instead of a + // list of generic callbacks. Then we can have two: one for legacy roots, one + // for concurrent roots. And this method would only flush the legacy ones. + if (includesLegacySyncCallbacks) { + flushSyncCallbacks(); } } -function flushSyncCallbackQueue() { +function flushSyncCallbacks() { if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. isFlushingSyncQueue = true; @@ -5665,13 +5779,14 @@ function flushSyncCallbackQueue() { } syncQueue = null; + includesLegacySyncCallbacks = false; } catch (error) { // If something throws, leave the remaining callbacks on the queue. if (syncQueue !== null) { syncQueue = syncQueue.slice(i + 1); } // Resume flushing in the next tick - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue); + scheduleCallback(ImmediatePriority, flushSyncCallbacks); throw error; } finally { setCurrentUpdatePriority(previousUpdatePriority); @@ -5697,29 +5812,7 @@ var Passive$1 = /* */ 4; -// TODO: this is special because it gets imported during build. -// -// TODO: 17.0.3 has not been released to NPM; -// It exists as a placeholder so that DevTools can support work tag changes between releases. -// When we next publish a release (either 17.0.3 or 17.1.0), update the matching TODO in backend/renderer.js -var ReactVersion = "17.0.3"; - -var NoMode = - /* */ - 0; // TODO: Remove ConcurrentMode by reading from the root tag instead - -var ConcurrentMode = - /* */ - 1; -var ProfileMode = - /* */ - 2; -var DebugTracingMode = - /* */ - 4; -var StrictLegacyMode = - /* */ - 8; +var ReactVersion = "17.0.3-2d8d133e1"; var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = 0; @@ -5739,7 +5832,6 @@ function is(x, y) { var objectIs = typeof Object.is === "function" ? Object.is : is; -var hasOwnProperty = Object.prototype.hasOwnProperty; /** * Performs equality by iterating through keys on an object and returning false * when any key has values which are not strictly equal between the arguments. @@ -6987,7 +7079,11 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { ); var callback = update.callback; - if (callback !== null) { + if ( + callback !== null && // If the update was already committed, we should not queue its + // callback again. + update.lane !== NoLane + ) { workInProgress.flags |= Callback; var effects = queue.effects; @@ -7097,8 +7193,7 @@ function commitUpdateQueue(finishedWork, finishedQueue, instance) { } } -var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7216,6 +7311,7 @@ function applyDerivedStateFromProps( updateQueue.baseState = memoizedState; } } + var classComponentUpdater = { isMounted: isMounted, enqueueSetState: function(inst, payload, callback) { @@ -7865,7 +7961,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; @@ -7894,9 +7989,14 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; + var fiberFlags = Update; + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + // Never double-invoke effects for legacy roots. + fiberFlags |= MountLayoutDev; } + + workInProgress.flags |= fiberFlags; } } @@ -7958,9 +8058,14 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; + var fiberFlags = Update; + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + // Never double-invoke effects for legacy roots. + fiberFlags |= MountLayoutDev; } + + workInProgress.flags |= fiberFlags; } return false; @@ -8006,17 +8111,27 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; + var _fiberFlags = Update; + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + // Never double-invoke effects for legacy roots. + _fiberFlags |= MountLayoutDev; } + + workInProgress.flags |= _fiberFlags; } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; + var _fiberFlags2 = Update; + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + // Never double-invoke effects for legacy roots. + _fiberFlags2 |= MountLayoutDev; } + + workInProgress.flags |= _fiberFlags2; } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8257,8 +8372,6 @@ var warnForMissingKey = function(child, returnFiber) {}; }; } -var isArray$1 = Array.isArray; - function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; @@ -8373,18 +8486,16 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { - if (returnFiber.type !== "textarea") { - var childString = Object.prototype.toString.call(newChild); + var childString = Object.prototype.toString.call(newChild); - { - throw Error( - "Objects are not valid as a React child (found: " + - (childString === "[object Object]" - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : childString) + - "). If you meant to render a collection of children, use an array instead." - ); - } + { + throw Error( + "Objects are not valid as a React child (found: " + + (childString === "[object Object]" + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : childString) + + "). If you meant to render a collection of children, use an array instead." + ); } } @@ -8640,7 +8751,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, @@ -8698,7 +8809,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -8753,7 +8864,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateFragment( @@ -9363,9 +9474,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild = newChild.props.children; } // Handle object types - var isObject = typeof newChild === "object" && newChild !== null; - - if (isObject) { + if (typeof newChild === "object" && newChild !== null) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return placeSingleChild( @@ -9387,6 +9496,26 @@ function ChildReconciler(shouldTrackSideEffects) { ) ); } + + if (isArray(newChild)) { + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + } + + if (getIteratorFn(newChild)) { + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); } if (typeof newChild === "string" || typeof newChild === "number") { @@ -9400,28 +9529,6 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray$1(newChild)) { - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - } - - if (getIteratorFn(newChild)) { - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - } - - if (isObject) { - throwOnInvalidObjectType(returnFiber, newChild); - } - { if (typeof newChild === "function") { warnOnFunctionType(returnFiber); @@ -9873,7 +9980,7 @@ function updateHookTypesDev() { function checkDepsAreArrayDev(deps) { { - if (deps !== undefined && deps !== null && !Array.isArray(deps)) { + if (deps !== undefined && deps !== null && !isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. error( @@ -10093,7 +10200,12 @@ function renderWithHooks( if ( current !== null && - (current.flags & PassiveStatic) !== (workInProgress.flags & PassiveStatic) + (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird + // and creates false positives. To make this work in legacy mode, we'd + // need to mark fibers that commit in an incomplete state, somehow. For + // now I'll disable the warning that most of the bugs that would trigger + // it are either exclusive to concurrent mode or exist in both. + (current.mode & ConcurrentMode) !== NoMode ) { error( "Internal React error: Expected static flag was missing. Please " + @@ -10116,7 +10228,14 @@ function bailoutHooks(current, workInProgress, lanes) { workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the // complete phase (bubbleProperties). - { + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags &= ~( + MountPassiveDev | + MountLayoutDev | + Passive | + Update + ); + } else { workInProgress.flags &= ~(Passive | Update); } @@ -10897,7 +11016,14 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { } function mountEffect(create, deps) { - { + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + return mountEffectImpl( + MountPassiveDev | Passive | PassiveStatic, + Passive$1, + create, + deps + ); + } else { return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); } } @@ -10907,9 +11033,13 @@ function updateEffect(create, deps) { } function mountLayoutEffect(create, deps) { - { - return mountEffectImpl(Update, Layout, create, deps); + var fiberFlags = Update; + + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + fiberFlags |= MountLayoutDev; } + + return mountEffectImpl(fiberFlags, Layout, create, deps); } function updateLayoutEffect(create, deps) { @@ -10961,15 +11091,18 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; + var fiberFlags = Update; - { - return mountEffectImpl( - Update, - Layout, - imperativeHandleEffect.bind(null, create, ref), - effectDeps - ); + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + fiberFlags |= MountLayoutDev; } + + return mountEffectImpl( + fiberFlags, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); } function updateImperativeHandle(ref, create, deps) { @@ -11145,7 +11278,7 @@ function mountTransition() { var start = startTransition.bind(null, setPending); var hook = mountWorkInProgressHook(); hook.memoizedState = start; - return [start, isPending]; + return [isPending, start]; } function updateTransition() { @@ -11154,7 +11287,7 @@ function updateTransition() { var hook = updateWorkInProgressHook(); var start = hook.memoizedState; - return [start, isPending]; + return [isPending, start]; } function rerenderTransition() { @@ -11163,7 +11296,7 @@ function rerenderTransition() { var hook = updateWorkInProgressHook(); var start = hook.memoizedState; - return [start, isPending]; + return [isPending, start]; } var isUpdatingOpaqueValueInRenderPhase = false; @@ -12573,10 +12706,6 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { nextBaseLanes = renderLanes; } // Schedule this fiber to re-render at offscreen priority. Then bailout. - { - markSpawnedWork(OffscreenLane); - } - workInProgress.lanes = workInProgress.childLanes = laneToLanes( OffscreenLane ); @@ -13341,17 +13470,6 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); - } - adoptClassInstance(workInProgress, value); mountClassInstance(workInProgress, Component, props, renderLanes); return finishClassComponent( @@ -13623,11 +13741,6 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { // it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } - return _fallbackFragment; } else { return mountSuspensePrimaryChildren( @@ -14111,11 +14224,12 @@ function validateTailOptions(tailMode, revealOrder) { function validateSuspenseListNestedChild(childSlot, index) { { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + var isAnArray = isArray(childSlot); + var isIterable = + !isAnArray && typeof getIteratorFn(childSlot) === "function"; - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; error( "A nested %s was passed to row #%s in . Wrap it in " + @@ -14143,7 +14257,7 @@ function validateSuspenseListChildren(children, revealOrder) { children !== null && children !== false ) { - if (Array.isArray(children)) { + if (isArray(children)) { for (var i = 0; i < children.length; i++) { if (!validateSuspenseListNestedChild(children[i], i)) { return; @@ -15750,7 +15864,7 @@ function completeWork(current, workInProgress, renderLanes) { var _primaryChildFragment2 = workInProgress.child; if (_primaryChildFragment2 !== null) { - // $FlowFixMe Flow doens't support type casting in combiation with the -= operator + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator workInProgress.treeBaseDuration -= _primaryChildFragment2.treeBaseDuration; } @@ -15889,10 +16003,6 @@ function completeWork(current, workInProgress, renderLanes) { // since we're leaving it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } } } else { cutOffTailIfNeeded(renderState, false); @@ -15949,10 +16059,6 @@ function completeWork(current, workInProgress, renderLanes) { // since we're leaving it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } } } @@ -16418,6 +16524,7 @@ function attachPingListener(root, wakeable, lanes) { // Memoize using the thread ID to prevent redundant listeners. threadIDs.add(lanes); var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); } } @@ -16651,10 +16758,9 @@ var didWarnAboutUndefinedSnapshotBeforeUpdate = null; { didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} - +} // Used during the commit phase to track the state of the Offscreen component stack. var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; -var nextEffect = null; +var nextEffect = null; // Used for Profiling builds to track updaters. var callComponentWillUnmountWithTimer = function(current, instance) { instance.props = current.memoizedProps; @@ -16663,7 +16769,7 @@ var callComponentWillUnmountWithTimer = function(current, instance) { { instance.componentWillUnmount(); } -}; // Capture errors so they don't interrupt unmounting. +}; // Capture errors so they don't interrupt mounting. function safelyCallComponentWillUnmount( current, @@ -16684,7 +16790,7 @@ function safelyCallComponentWillUnmount( captureCommitPhaseError(current, nearestMountedAncestor, unmountError); } } -} +} // Capture errors so they don't interrupt mounting. function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; @@ -17211,17 +17317,14 @@ function commitLayoutEffectOnFiber( var phase = current === null ? "mount" : "update"; if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - phase, - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime + ); } } @@ -17596,13 +17699,8 @@ function attachSuspenseRetryListeners(finishedWork) { var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } - retryCache.add(wakeable); + wakeable.then(retry, retry); } }); @@ -17624,7 +17722,7 @@ function isSuspenseBoundaryBeingHidden(current, finishedWork) { return false; } -function commitMutationEffects(root, firstChild) { +function commitMutationEffects(root, firstChild, committedLanes) { nextEffect = firstChild; commitMutationEffects_begin(root); } @@ -17765,6 +17863,9 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { } function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; + while (nextEffect !== null) { var fiber = nextEffect; var firstChild = fiber.child; @@ -17779,6 +17880,9 @@ function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { } function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; + while (nextEffect !== null) { var fiber = nextEffect; @@ -18089,6 +18193,152 @@ function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { fiber.return = expectedReturnFiber; } +function invokeLayoutEffectMountInDEV(fiber) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + invokeGuardedCallback( + null, + commitHookEffectListMount, + null, + Layout | HasEffect, + fiber + ); + + if (hasCaughtError()) { + var mountError = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, mountError); + } + + break; + } + + case ClassComponent: { + var instance = fiber.stateNode; + invokeGuardedCallback(null, instance.componentDidMount, instance); + + if (hasCaughtError()) { + var _mountError = clearCaughtError(); + + captureCommitPhaseError(fiber, fiber.return, _mountError); + } + + break; + } + } + } +} + +function invokePassiveEffectMountInDEV(fiber) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + invokeGuardedCallback( + null, + commitHookEffectListMount, + null, + Passive$1 | HasEffect, + fiber + ); + + if (hasCaughtError()) { + var mountError = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, mountError); + } + + break; + } + } + } +} + +function invokeLayoutEffectUnmountInDEV(fiber) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + invokeGuardedCallback( + null, + commitHookEffectListUnmount, + null, + Layout | HasEffect, + fiber, + fiber.return + ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, unmountError); + } + + break; + } + + case ClassComponent: { + var instance = fiber.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + invokeGuardedCallback( + null, + safelyCallComponentWillUnmount, + null, + fiber, + fiber.return, + instance + ); + + if (hasCaughtError()) { + var _unmountError = clearCaughtError(); + + captureCommitPhaseError(fiber, fiber.return, _unmountError); + } + } + + break; + } + } + } +} + +function invokePassiveEffectUnmountInDEV(fiber) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + invokeGuardedCallback( + null, + commitHookEffectListUnmount, + null, + Passive$1 | HasEffect, + fiber, + fiber.return + ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, unmountError); + } + + break; + } + } + } +} + var COMPONENT_TYPE = 0; var HAS_PSEUDO_CLASS_TYPE = 1; var ROLE_TYPE = 2; @@ -18107,6 +18357,7 @@ if (typeof Symbol === "function" && Symbol.for) { var ceil = Math.ceil; var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ @@ -18195,13 +18446,7 @@ var NESTED_UPDATE_LIMIT = 50; var nestedUpdateCount = 0; var rootWithNestedUpdates = null; var NESTED_PASSIVE_UPDATE_LIMIT = 50; -var nestedPassiveUpdateCount = 0; // Marks the need to reschedule pending interactions at these lanes -// 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. -// TODO: Can use a bitmask instead of an array - -var spawnedWorkDuringRender = null; // If two updates are scheduled within the same event, we should treat their +var nestedPassiveUpdateCount = 0; // If two updates are scheduled within the same event, we should treat their // event times as simultaneous, even if the actual clock time has advanced // between the first and second call. @@ -18295,7 +18540,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (root === null) { warnAboutUpdateOnUnmountedFiberInDEV(fiber); return null; - } // Mark that the root has a pending update. + } markRootUpdated(root, lane, eventTime); @@ -18329,15 +18574,12 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { (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, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed + // 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. - performSyncWorkOnRoot(root); } else { ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, lane); if ( executionContext === NoContext && @@ -18349,13 +18591,12 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { // without immediately flushing it. We only do this for user-initiated // updates, to preserve historical behavior of legacy mode. resetRenderTimer(); - flushSyncCallbackQueue(); + flushSyncCallbacksOnlyInLegacyMode(); } } } else { // Schedule other updates after in case the callback is sync. ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, lane); } return root; @@ -18483,11 +18724,15 @@ function ensureRootIsScheduled(root, currentTime) { if (newCallbackPriority === SyncLane) { // Special case: Sync React callbacks are scheduled on a special // internal queue - scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + if (root.tag === LegacyRoot) { + scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else { + scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + } { // Flush the queue in an Immediate task. - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue); + scheduleCallback(ImmediatePriority, flushSyncCallbacks); } newCallbackNode = null; @@ -18561,20 +18806,17 @@ function performConcurrentWorkOnRoot(root, didTimeout) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; - } // TODO: We only check `didTimeout` defensively, to account for a Scheduler + } // We disable time-slicing in some cases: if the work has been CPU-bound + // for too long ("expired" work, to prevent starvation), or we're in + // sync-updates-by-default mode. + // TODO: We only check `didTimeout` defensively, to account for a Scheduler // bug we're still investigating. Once the bug in Scheduler is fixed, // we can remove this, since we track expiration ourselves. - if (didTimeout) { - // Something expired. Flush synchronously until there's no expired - // work left. - markRootExpired(root, lanes); // This will schedule a synchronous callback. - - ensureRootIsScheduled(root, now()); - return null; - } - - var exitStatus = renderRootConcurrent(root, lanes); + var exitStatus = + shouldTimeSlice(root, lanes) && !didTimeout + ? renderRootConcurrent(root, lanes) + : renderRootSync(root, lanes); if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { @@ -18594,10 +18836,11 @@ function performConcurrentWorkOnRoot(root, didTimeout) { // all pending updates are included. If it still fails after the second // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { - exitStatus = renderRootSync(root, lanes); + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = renderRootSync(root, errorRetryLanes); } } @@ -18762,22 +19005,16 @@ function performSyncWorkOnRoot(root) { } flushPassiveEffects(); - var lanes; - var exitStatus; + var lanes = getNextLanes(root, NoLanes); - if ( - root === workInProgressRoot && - areLanesExpired(root, workInProgressRootRenderLanes) - ) { - // There's a partial tree, and at least one of its lanes has expired. Finish - // rendering it before rendering the rest of the expired work. - lanes = workInProgressRootRenderLanes; - exitStatus = renderRootSync(root, lanes); - } else { - lanes = getNextLanes(root, NoLanes); - exitStatus = renderRootSync(root, lanes); + if (!includesSomeLane(lanes, SyncLane)) { + // There's no remaining sync work left. + ensureRootIsScheduled(root, now()); + return null; } + var exitStatus = renderRootSync(root, lanes); + if (root.tag !== LegacyRoot && exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. @@ -18795,9 +19032,10 @@ function performSyncWorkOnRoot(root) { // all pending updates are included. If it still fails after the second // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; exitStatus = renderRootSync(root, lanes); } } @@ -18819,7 +19057,7 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; -} // TODO: Do we still need this API? I think we can delete it. Was only used +} function batchedUpdates$1(fn, a) { var prevExecutionContext = executionContext; executionContext |= BatchedContext; @@ -18827,21 +19065,23 @@ function batchedUpdates$1(fn, a) { try { return fn(a); } finally { - executionContext = prevExecutionContext; + executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer + // most batchedUpdates-like method. if (executionContext === NoContext) { - // Flush the immediate callbacks that were scheduled during this batch resetRenderTimer(); - flushSyncCallbackQueue(); + flushSyncCallbacksOnlyInLegacyMode(); } } } function flushSync(fn, a) { var prevExecutionContext = executionContext; executionContext |= BatchedContext; + var prevTransition = ReactCurrentBatchConfig$2.transition; var previousPriority = getCurrentUpdatePriority(); try { + ReactCurrentBatchConfig$2.transition = 0; setCurrentUpdatePriority(DiscreteEventPriority); if (fn) { @@ -18851,12 +19091,13 @@ function flushSync(fn, a) { } } finally { setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; 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. if ((executionContext & (RenderContext | CommitContext)) === NoContext) { - flushSyncCallbackQueue(); + flushSyncCallbacks(); } else { { error( @@ -18913,10 +19154,6 @@ function prepareFreshStack(root, lanes) { workInProgressRootPingedLanes = NoLanes; enqueueInterleavedUpdates(); - { - spawnedWorkDuringRender = null; - } - { ReactStrictModeWarnings.discardPendingWarnings(); } @@ -19005,20 +19242,6 @@ function popDispatcher(prevDispatcher) { ReactCurrentDispatcher$2.current = prevDispatcher; } -function pushInteractions(root) { - { - var prevInteractions = tracing.__interactionsRef.current; - tracing.__interactionsRef.current = root.memoizedInteractions; - return prevInteractions; - } -} - -function popInteractions(prevInteractions) { - { - tracing.__interactionsRef.current = prevInteractions; - } -} - function markCommitTimeOfFallback() { globalMostRecentFallbackTime = now(); } @@ -19078,11 +19301,8 @@ function renderRootSync(root, lanes) { if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { prepareFreshStack(root, lanes); - startWorkOnPendingInteractions(root, lanes); } - var prevInteractions = pushInteractions(root); - do { try { workLoopSync(); @@ -19093,11 +19313,6 @@ function renderRootSync(root, lanes) { } while (true); resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - executionContext = prevExecutionContext; popDispatcher(prevDispatcher); @@ -19133,11 +19348,8 @@ function renderRootConcurrent(root, lanes) { if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { resetRenderTimer(); prepareFreshStack(root, lanes); - startWorkOnPendingInteractions(root, lanes); } - var prevInteractions = pushInteractions(root); - do { try { workLoopConcurrent(); @@ -19148,11 +19360,6 @@ function renderRootConcurrent(root, lanes) { } while (true); resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - popDispatcher(prevDispatcher); executionContext = prevExecutionContext; @@ -19296,11 +19503,14 @@ function commitRoot(root) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); + var prevTransition = ReactCurrentBatchConfig$2.transition; try { + ReactCurrentBatchConfig$2.transition = 0; setCurrentUpdatePriority(DiscreteEventPriority); commitRootImpl(root, previousUpdateLanePriority); } finally { + ReactCurrentBatchConfig$2.transition = prevTransition; setCurrentUpdatePriority(previousUpdateLanePriority); } @@ -19329,6 +19539,15 @@ function commitRootImpl(root, renderPriorityLevel) { if (finishedWork === null) { return null; + } else { + { + if (lanes === NoLanes) { + error( + "root.finishedLanes should not be empty during a commit. This is a " + + "bug in React." + ); + } + } } root.finishedWork = null; @@ -19386,11 +19605,12 @@ function commitRootImpl(root, renderPriorityLevel) { NoFlags; if (subtreeHasEffects || rootHasEffect) { + var prevTransition = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; var previousPriority = getCurrentUpdatePriority(); setCurrentUpdatePriority(DiscreteEventPriority); var prevExecutionContext = executionContext; - executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles + executionContext |= CommitContext; // Reset this to null before calling lifecycles ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass // of the effect list for each phase: all mutation effects come before all @@ -19423,14 +19643,10 @@ function commitRootImpl(root, renderPriorityLevel) { // opportunity to paint. requestPaint(); - - { - popInteractions(prevInteractions); - } - executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value. setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; } else { // No effects. root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were @@ -19454,24 +19670,7 @@ function commitRootImpl(root, renderPriorityLevel) { remainingLanes = root.pendingLanes; // Check if there's remaining work on this root - if (remainingLanes !== NoLanes) { - { - if (spawnedWorkDuringRender !== null) { - var expirationTimes = spawnedWorkDuringRender; - spawnedWorkDuringRender = null; - - for (var i = 0; i < expirationTimes.length; i++) { - scheduleInteractions( - root, - expirationTimes[i], - root.memoizedInteractions - ); - } - } - - schedulePendingInteractions(root, remainingLanes); - } - } else { + if (remainingLanes === NoLanes) { // If there's no remaining work, we can clear the set of already failed // error boundaries. legacyErrorBoundariesThatAlreadyFailed = null; @@ -19479,11 +19678,7 @@ function commitRootImpl(root, renderPriorityLevel) { { 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, lanes); + commitDoubleInvokeEffectsInDEV(root.current, false); } } @@ -19507,9 +19702,9 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var error = firstUncaughtError; + var error$1 = firstUncaughtError; firstUncaughtError = null; - throw error; + throw error$1; } if ((executionContext & LegacyUnbatchedContext) !== NoContext) { @@ -19518,27 +19713,47 @@ function commitRootImpl(root, renderPriorityLevel) { // of the batch. return null; + } // If the passive effects are the result of a discrete render, flush them + // synchronously at the end of the current task so that the result is + // immediately observable. Otherwise, we assume that they are not + // order-dependent and do not need to be observed by external systems, so we + // can wait until after paint. + // TODO: We can optimize this by not scheduling the callback earlier. Since we + // currently schedule the callback in multiple places, will wait until those + // are consolidated. + + if ( + includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && + root.tag !== LegacyRoot + ) { + flushPassiveEffects(); } // If layout work was scheduled, flush it now. - flushSyncCallbackQueue(); + flushSyncCallbacks(); return null; } function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsLanes !== NoLanes) { - var priority = higherEventPriority( - DefaultEventPriority, - lanesToEventPriority(pendingPassiveEffectsLanes) - ); + // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should + // probably just combine the two functions. I believe they were only separate + // in the first place because we used to wrap it with + // `Scheduler.runWithPriority`, which accepts a function. But now we track the + // priority within React itself, so we can mutate the variable directly. + if (rootWithPendingPassiveEffects !== null) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes); + var priority = lowerEventPriority(DefaultEventPriority, renderPriority); + var prevTransition = ReactCurrentBatchConfig$2.transition; var previousPriority = getCurrentUpdatePriority(); try { + ReactCurrentBatchConfig$2.transition = 0; setCurrentUpdatePriority(priority); return flushPassiveEffectsImpl(); } finally { setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; } } @@ -19551,8 +19766,10 @@ function flushPassiveEffectsImpl() { } var root = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; - rootWithPendingPassiveEffects = null; + rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects. + // Figure out why and fix it. It's not causing any known issues (probably + // because it's only used for profiling), but it's a refactor hazard. + pendingPassiveEffectsLanes = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -19565,25 +19782,26 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); commitPassiveUnmountEffects(root.current); commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects { - popInteractions(prevInteractions); - finishPendingInteractions(root, lanes); + isFlushingPassiveEffects = false; } { - isFlushingPassiveEffects = false; + commitDoubleInvokeEffectsInDEV(root.current, true); } executionContext = prevExecutionContext; - flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this + flushSyncCallbacks(); // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. nestedPassiveUpdateCount = - rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; + rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; // TODO: Move to commitPassiveMountEffects + + onPostCommitRoot(root); + return true; } @@ -19620,7 +19838,6 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { if (root !== null) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, SyncLane); } } @@ -19660,7 +19877,6 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { if (root !== null) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, SyncLane); } return; @@ -19728,7 +19944,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { } ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, pingedLanes); } function retryTimedOutBoundary(boundaryFiber, retryLane) { @@ -19748,7 +19963,6 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { if (root !== null) { markRootUpdated(root, retryLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, retryLane); } } function resolveRetryWakeable(boundaryFiber, wakeable) { @@ -19829,6 +20043,63 @@ function flushRenderPhaseStrictModeWarningsInDEV() { } } +function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) { + { + // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects + // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level. + // Maybe not a big deal since this is DEV only behavior. + setCurrentFiber(fiber); + invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV); + + if (hasPassiveEffects) { + invokeEffectsInDev( + fiber, + MountPassiveDev, + invokePassiveEffectUnmountInDEV + ); + } + + invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV); + + if (hasPassiveEffects) { + invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV); + } + + resetCurrentFiber(); + } +} + +function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + var current = firstChild; + var subtreeRoot = null; + + while (current !== null) { + var primarySubtreeFlag = current.subtreeFlags & fiberFlags; + + if ( + current !== subtreeRoot && + current.child !== null && + primarySubtreeFlag !== NoFlags + ) { + current = current.child; + } else { + if ((current.flags & fiberFlags) !== NoFlags) { + invokeEffectFn(current); + } + + if (current.sibling !== null) { + current = current.sibling; + } else { + current = subtreeRoot = current.return; + } + } + } + } +} + var didWarnStateUpdateForNotYetMountedComponent = null; function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { @@ -20134,144 +20405,6 @@ function warnIfUnmockedScheduler(fiber) { } } } -} - -function computeThreadID(root, lane) { - // Interaction threads are unique per root and expiration time. - // NOTE: Intentionally unsound cast. All that matters is that it's a number - // and it represents a batch of work. Could make a helper function instead, - // but meh this is fine for now. - return lane * 1000 + root.interactionThreadID; -} - -function markSpawnedWork(lane) { - if (spawnedWorkDuringRender === null) { - spawnedWorkDuringRender = [lane]; - } else { - spawnedWorkDuringRender.push(lane); - } -} - -function scheduleInteractions(root, lane, interactions) { - if (interactions.size > 0) { - var pendingInteractionMap = root.pendingInteractionMap; - var pendingInteractions = pendingInteractionMap.get(lane); - - 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(lane, 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, lane); - subscriber.onWorkScheduled(interactions, threadID); - } - } -} - -function schedulePendingInteractions(root, lane) { - scheduleInteractions(root, lane, tracing.__interactionsRef.current); -} - -function startWorkOnPendingInteractions(root, lanes) { - // 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, - scheduledLane - ) { - if (includesSomeLane(lanes, scheduledLane)) { - 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 performConcurrentWorkOnRoot() - // 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, lanes); - - 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, committedLanes) { - var remainingLanesAfterCommit = root.pendingLanes; - var subscriber; - - try { - subscriber = tracing.__subscriberRef.current; - - if (subscriber !== null && root.memoizedInteractions.size > 0) { - // FIXME: More than one lane can finish in a single commit. - var threadID = computeThreadID(root, committedLanes); - 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, lane) { - // 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 (!includesSomeLane(remainingLanesAfterCommit, lane)) { - pendingInteractionMap.delete(lane); - 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; - }); - } - } - }); - } - }); - } } // `act` testing API function shouldForceFlushFallbacksInDEV() { @@ -21016,21 +21149,32 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag, strictModeLevelOverride) { +function createHostRootFiber( + tag, + isStrictMode, + concurrentUpdatesByDefaultOverride +) { var mode; if (tag === ConcurrentRoot) { mode = ConcurrentMode; - if (strictModeLevelOverride !== null) { - if (strictModeLevelOverride >= 1) { - mode |= StrictLegacyMode; - } - } else { + if (isStrictMode === true) { + mode |= StrictLegacyMode; + { - mode |= StrictLegacyMode; + mode |= StrictEffectsMode; } } + + if ( + // We only use this flag for our repo tests to check both behaviors. + // TODO: Flip this flag and rename it something like "forceConcurrentByDefaultForTesting" + // Only for internal experiments. + concurrentUpdatesByDefaultOverride + ) { + mode |= ConcurrentUpdatesByDefaultMode; + } } else { mode = NoMode; } @@ -21081,16 +21225,8 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: - fiberTag = Mode; // Legacy strict mode ( without any level prop) defaults to level 1. - - var level = - pendingProps.unstable_level == null ? 1 : pendingProps.unstable_level; // Levels cascade; higher levels inherit all lower level modes. - // It is explicitly not supported to lower a mode with nesting, only to increase it. - - if (level >= 1) { - mode |= StrictLegacyMode; - } - + fiberTag = Mode; + mode |= StrictLegacyMode | StrictEffectsMode; break; case REACT_PROFILER_TYPE: @@ -21228,7 +21364,10 @@ function createFiberFromFragment(elements, mode, lanes, key) { function createFiberFromProfiler(pendingProps, mode, lanes, key) { { if (typeof pendingProps.id !== "string") { - error('Profiler must specify an "id" as a prop'); + error( + 'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', + typeof pendingProps.id + ); } } @@ -21355,17 +21494,12 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.pendingLanes = NoLanes; this.suspendedLanes = NoLanes; this.pingedLanes = NoLanes; + this.expiredLanes = NoLanes; this.mutableReadLanes = NoLanes; this.finishedLanes = NoLanes; this.entangledLanes = NoLanes; this.entanglements = createLaneMap(NoLanes); - { - this.interactionThreadID = tracing.unstable_getThreadID(); - this.memoizedInteractions = new Set(); - this.pendingInteractionMap = new Map(); - } - { switch (tag) { case ConcurrentRoot: @@ -21384,12 +21518,17 @@ function createFiberRoot( tag, hydrate, hydrationCallbacks, - strictModeLevelOverride + isStrictMode, + concurrentUpdatesByDefaultOverride ) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); + var uninitializedFiber = createHostRootFiber( + tag, + isStrictMode, + concurrentUpdatesByDefaultOverride + ); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -21527,14 +21666,16 @@ function createContainer( tag, hydrate, hydrationCallbacks, - strictModeLevelOverride + isStrictMode, + concurrentUpdatesByDefaultOverride ) { return createFiberRoot( containerInfo, tag, hydrate, hydrationCallbacks, - strictModeLevelOverride + isStrictMode, + concurrentUpdatesByDefaultOverride ); } function updateContainer(element, container, parentComponent, callback) { @@ -21642,10 +21783,10 @@ var setSuspenseHandler = null; { var copyWithDeleteImpl = function(obj, path, index) { var key = path[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); if (index + 1 === path.length) { - if (Array.isArray(updated)) { + if (isArray(updated)) { updated.splice(key, 1); } else { delete updated[key]; @@ -21664,14 +21805,14 @@ var setSuspenseHandler = null; var copyWithRenameImpl = function(obj, oldPath, newPath, index) { var oldKey = oldPath[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); if (index + 1 === oldPath.length) { var newKey = newPath[index]; // $FlowFixMe number or string is fine here updated[newKey] = updated[oldKey]; - if (Array.isArray(updated)) { + if (isArray(updated)) { updated.splice(oldKey, 1); } else { delete updated[oldKey]; @@ -21716,7 +21857,7 @@ var setSuspenseHandler = null; } var key = path[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); return updated; @@ -21873,7 +22014,10 @@ function injectIntoDevTools(devToolsConfig) { scheduleRoot: scheduleRoot, setRefreshHandler: setRefreshHandler, // Enables DevTools to append owner stacks to error messages in DEV mode. - getCurrentFiber: getCurrentFiberForDevTools + getCurrentFiber: getCurrentFiberForDevTools, + // Enables DevTools to detect reconciler version rather than renderer version + // which may not match for third party renderers. + reconcilerVersion: ReactVersion }); } @@ -22290,13 +22434,20 @@ function sendAccessibilityEvent(handle, eventType) { } } -function render(element, containerTag, callback) { +function render(element, containerTag, callback, concurrentRoot) { 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, LegacyRoot, false, null, null); + root = createContainer( + containerTag, + concurrentRoot ? ConcurrentRoot : LegacyRoot, + false, + null, + false, + null + ); roots.set(containerTag, root); } diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.js b/Libraries/Renderer/implementations/ReactFabric-dev.js index e08d68b542c96c..6899cf9d416be1 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactFabric-dev * @preventMunge - * @generated + * @generated SignedSource<<64e2487c0986fc70b80db55f5a1cbb38>> */ 'use strict'; @@ -21,7 +21,6 @@ var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); var Scheduler = require("scheduler"); -var tracing = require("scheduler/tracing"); var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; @@ -381,6 +380,12 @@ function clearCaughtError() { } } +var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare + +function isArray(a) { + return isArrayImpl(a); +} + var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -408,13 +413,13 @@ var validateEventDispatches; validateEventDispatches = function(event) { var dispatchListeners = event._dispatchListeners; var dispatchInstances = event._dispatchInstances; - var listenersIsArr = Array.isArray(dispatchListeners); + var listenersIsArr = isArray(dispatchListeners); var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; - var instancesIsArr = Array.isArray(dispatchInstances); + var instancesIsArr = isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances @@ -451,7 +456,7 @@ function executeDispatchesInOrder(event) { validateEventDispatches(event); } - if (Array.isArray(dispatchListeners)) { + if (isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; @@ -482,7 +487,7 @@ function executeDispatchesInOrderStopAtTrueImpl(event) { validateEventDispatches(event); } - if (Array.isArray(dispatchListeners)) { + if (isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; @@ -528,7 +533,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners; var dispatchInstance = event._dispatchInstances; - if (!!Array.isArray(dispatchListener)) { + if (!!isArray(dispatchListener)) { throw Error("executeDirectDispatch(...): Invalid `event`."); } @@ -1085,8 +1090,19 @@ function printTouchBank() { return printed; } +var instrumentationCallback; var ResponderTouchHistoryStore = { + /** + * Registers a listener which can be used to instrument every touch event. + */ + instrument: function(callback) { + instrumentationCallback = callback; + }, recordTouchTrack: function(topLevelType, nativeEvent) { + if (instrumentationCallback != null) { + instrumentationCallback(topLevelType, nativeEvent); + } + if (isMoveish(topLevelType)) { nativeEvent.changedTouches.forEach(recordTouchMove); } else if (isStartish(topLevelType)) { @@ -1144,11 +1160,11 @@ function accumulate(current, next) { } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { + if (isArray(current)) { return current.concat(next); } - if (Array.isArray(next)) { + if (isArray(next)) { return [current].concat(next); } @@ -1180,8 +1196,8 @@ function accumulateInto(current, next) { } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { - if (Array.isArray(next)) { + if (isArray(current)) { + if (isArray(next)) { current.push.apply(current, next); return current; } @@ -1190,7 +1206,7 @@ function accumulateInto(current, next) { return current; } - if (Array.isArray(next)) { + if (isArray(next)) { // A bit too dangerous to mutate `next`. return [current].concat(next); } @@ -1238,10 +1254,10 @@ var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; -var FundamentalComponent = 20; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; +var CacheComponent = 24; /** * Instance of element that should respond to touch/move types of interactions, @@ -2494,14 +2510,40 @@ function getFiberCurrentPropsFromNode$1(inst) { // Module provided by RN: var ReactFabricGlobalResponderHandler = { onChange: function(from, to, blockNativeResponder) { - if (to !== null) { - var tag = to.stateNode.canonical._nativeTag; - ReactNativePrivateInterface.UIManager.setJSResponder( - tag, - blockNativeResponder - ); + var fromOrTo = from || to; + var fromOrToStateNode = fromOrTo && fromOrTo.stateNode; + var isFabric = !!( + fromOrToStateNode && fromOrToStateNode.canonical._internalInstanceHandle + ); + + if (isFabric) { + if (from) { + // equivalent to clearJSResponder + nativeFabricUIManager.setIsJSResponder( + from.stateNode.node, + false, + blockNativeResponder || false + ); + } + + if (to) { + // equivalent to setJSResponder + nativeFabricUIManager.setIsJSResponder( + to.stateNode.node, + true, + blockNativeResponder || false + ); + } } else { - ReactNativePrivateInterface.UIManager.clearJSResponder(); + if (to !== null) { + var tag = to.stateNode.canonical._nativeTag; + ReactNativePrivateInterface.UIManager.setJSResponder( + tag, + blockNativeResponder + ); + } else { + ReactNativePrivateInterface.UIManager.clearJSResponder(); + } } } }; @@ -2548,12 +2590,12 @@ var REACT_SUSPENSE_TYPE = 0xead1; var REACT_SUSPENSE_LIST_TYPE = 0xead8; var REACT_MEMO_TYPE = 0xead3; var REACT_LAZY_TYPE = 0xead4; -var REACT_FUNDAMENTAL_TYPE = 0xead5; var REACT_SCOPE_TYPE = 0xead7; var REACT_OPAQUE_ID_TYPE = 0xeae0; var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; var REACT_OFFSCREEN_TYPE = 0xeae2; var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; +var REACT_CACHE_TYPE = 0xeae4; if (typeof Symbol === "function" && Symbol.for) { var symbolFor = Symbol.for; @@ -2569,12 +2611,12 @@ if (typeof Symbol === "function" && Symbol.for) { REACT_SUSPENSE_LIST_TYPE = symbolFor("react.suspense_list"); REACT_MEMO_TYPE = symbolFor("react.memo"); REACT_LAZY_TYPE = symbolFor("react.lazy"); - REACT_FUNDAMENTAL_TYPE = symbolFor("react.fundamental"); REACT_SCOPE_TYPE = symbolFor("react.scope"); REACT_OPAQUE_ID_TYPE = symbolFor("react.opaque.id"); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2596,18 +2638,23 @@ function getIteratorFn(maybeIterable) { } function getWrappedName(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + + if (displayName) { + return displayName; + } + var functionName = innerType.displayName || innerType.name || ""; - return ( - outerType.displayName || - (functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName) - ); -} + return functionName !== "" + ? wrapperName + "(" + functionName + ")" + : wrapperName; +} // Keep in sync with react-reconciler/getComponentNameFromFiber function getContextName(type) { return type.displayName || "Context"; -} +} // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. -function getComponentName(type) { +function getComponentNameFromType(type) { if (type == null) { // Host root, text node or just invalid type. return null; @@ -2616,7 +2663,7 @@ function getComponentName(type) { { if (typeof type.tag === "number") { error( - "Received an unexpected object in getComponentName(). " + + "Received an unexpected object in getComponentNameFromType(). " + "This is likely a bug in React. Please file an issue." ); } @@ -2648,6 +2695,9 @@ function getComponentName(type) { case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + + case REACT_CACHE_TYPE: + return "Cache"; } if (typeof type === "object") { @@ -2664,7 +2714,13 @@ function getComponentName(type) { return getWrappedName(type, type.render, "ForwardRef"); case REACT_MEMO_TYPE: - return getComponentName(type.type); + var outerName = type.displayName || null; + + if (outerName !== null) { + return outerName; + } + + return getComponentNameFromType(type.type) || "Memo"; case REACT_LAZY_TYPE: { var lazyComponent = type; @@ -2672,7 +2728,7 @@ function getComponentName(type) { var init = lazyComponent._init; try { - return getComponentName(init(payload)); + return getComponentNameFromType(init(payload)); } catch (x) { return null; } @@ -2683,9 +2739,113 @@ function getComponentName(type) { return null; } +function getWrappedName$1(outerType, innerType, wrapperName) { + var functionName = innerType.displayName || innerType.name || ""; + return ( + outerType.displayName || + (functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName) + ); +} // Keep in sync with shared/getComponentNameFromType + +function getContextName$1(type) { + return type.displayName || "Context"; +} + +function getComponentNameFromFiber(fiber) { + var tag = fiber.tag, + type = fiber.type; + + switch (tag) { + case CacheComponent: + return "Cache"; + + case ContextConsumer: + var context = type; + return getContextName$1(context) + ".Consumer"; + + case ContextProvider: + var provider = type; + return getContextName$1(provider._context) + ".Provider"; + + case DehydratedFragment: + return "DehydratedFragment"; + + case ForwardRef: + return getWrappedName$1(type, type.render, "ForwardRef"); + + case Fragment: + return "Fragment"; + + case HostComponent: + // Host component type is the display name (e.g. "div", "View") + return type; + + case HostPortal: + return "Portal"; + + case HostRoot: + return "Root"; + + case HostText: + return "Text"; + + case LazyComponent: + // Name comes from the type in this case; we don't have a tag. + return getComponentNameFromType(type); + + case LegacyHiddenComponent: + return "LegacyHidden"; + + case Mode: + if (type === REACT_STRICT_MODE_TYPE) { + // Don't be less specific than shared/getComponentNameFromType + return "StrictMode"; + } + + return "Mode"; + + case OffscreenComponent: + return "Offscreen"; + + case Profiler: + return "Profiler"; + + case ScopeComponent: + return "Scope"; + + case SuspenseComponent: + return "Suspense"; + + case SuspenseListComponent: + return "SuspenseList"; + // The display name for this tags come from the user-provided type: + + case ClassComponent: + case FunctionComponent: + case IncompleteClassComponent: + case IndeterminateComponent: + case MemoComponent: + case SimpleMemoComponent: + if (typeof type === "function") { + return type.displayName || type.name || null; + } + + if (typeof type === "string") { + return type; + } + + break; + } + + return null; +} + var enableProfilerTimer = true; +var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; +var deferRenderPhaseUpdateToNextBatch = true; +var enableLazyContextPropagation = false; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -2703,53 +2863,86 @@ var Update = 4; var PlacementAndUpdate = /* */ - 6; -var Deletion = - /* */ - 8; + Placement | Update; +var ChildDeletion = + /* */ + 16; var ContentReset = /* */ - 16; + 32; var Callback = /* */ - 32; + 64; var DidCapture = /* */ - 64; + 128; var Ref = /* */ - 128; + 256; var Snapshot = /* */ - 256; + 512; var Passive = /* */ - 512; + 1024; var Hydrating = /* */ - 1024; + 2048; var HydratingAndUpdate = /* */ - 1028; + Hydrating | Update; +var Visibility = + /* */ + 4096; var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ - 4095; // These are not really side effects, but we still reuse this field. + 8191; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ - 4096; + 8192; var ShouldCapture = /* */ - 8192; // TODO (effects) Remove this bit once the new reconciler is synced to the old. - -var PassiveUnmountPendingDev = - /* */ 16384; var ForceUpdateForLegacySuspense = /* */ - 32768; // Static tags describe aspects of a fiber that are not specific to a render, + 32768; +// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). +// This enables us to defer more work in the unmount case, +// since we can defer traversing the tree during layout to look for Passive effects, +// and instead rely on the static flag as a signal that there may be cleanup work. + +var RefStatic = + /* */ + 262144; +var LayoutStatic = + /* */ + 524288; +var PassiveStatic = + /* */ + 1048576; // These flags allow us to traverse to fibers that have effects on mount +// don't contain effects, by checking subtreeFlags. + +var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity + // flag logic (see #20043) + Update | Snapshot | 0; +var MutationMask = + Placement | + Update | + ChildDeletion | + ContentReset | + Ref | + Hydrating | + Visibility; +var LayoutMask = Update | Callback | Ref; // TODO: Split into PassiveMountMask and PassiveUnmountMask + +var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. +// This allows certain concepts to persist without recalculting them, +// e.g. whether a subtree contains passive effects or portals. + +var StaticMask = LayoutStatic | PassiveStatic | RefStatic; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -2806,7 +2999,7 @@ function isMounted(component) { "never access something that requires stale data from the previous " + "render, such as refs. Move this logic to componentDidMount and " + "componentDidUpdate instead.", - getComponentName(ownerFiber.type) || "A component" + getComponentNameFromFiber(ownerFiber) || "A component" ); } @@ -2989,38 +3182,28 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null + ? findCurrentHostFiberImpl(currentParent) + : null; +} - if (!currentParent) { - return null; - } // Next we'll drill down this component to find the first HostComponent/Text. - - var node = currentParent; - - while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - return node; - } else if (node.child) { - node.child.return = node; - node = node.child; - continue; - } +function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } - if (node === currentParent) { - return null; - } + var child = node.child; - while (!node.sibling) { - if (!node.return || node.return === currentParent) { - return null; - } + while (child !== null) { + var match = findCurrentHostFiberImpl(child); - node = node.return; + if (match !== null) { + return match; } - node.sibling.return = node.return; - node = node.sibling; - } // Flow needs the return null here, but ESLint complains about it. - // eslint-disable-next-line no-unreachable + child = child.sibling; + } return null; } @@ -3107,7 +3290,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) { + if (isArray(node)) { var i = node.length; while (i-- && removedKeyCount > 0) { @@ -3232,12 +3415,12 @@ function diffNestedProperty( return updatePayload; } - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) { + if (!isArray(prevProp) && !isArray(nextProp)) { // Both are leaves, we can diff the leaves. return diffProperties(updatePayload, prevProp, nextProp, validAttributes); } - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArray(prevProp) && isArray(nextProp)) { // Both are arrays, we can diff the arrays. return diffNestedArrayProperty( updatePayload, @@ -3247,7 +3430,7 @@ function diffNestedProperty( ); } - if (Array.isArray(prevProp)) { + if (isArray(prevProp)) { return diffProperties( updatePayload, // $FlowFixMe - We know that this is always an object when the input is. ReactNativePrivateInterface.flattenStyle(prevProp), // $FlowFixMe - We know that this isn't an array because of above flow. @@ -3274,7 +3457,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { return updatePayload; } - if (!Array.isArray(nextProp)) { + if (!isArray(nextProp)) { // Add each property of the leaf. return addProperties(updatePayload, nextProp, validAttributes); } @@ -3300,7 +3483,7 @@ function clearNestedProperty(updatePayload, prevProp, validAttributes) { return updatePayload; } - if (!Array.isArray(prevProp)) { + if (!isArray(prevProp)) { // Add each property of the leaf. return clearProperties(updatePayload, prevProp, validAttributes); } @@ -3555,7 +3738,6 @@ function batchedUpdates(fn, bookkeeping) { function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, - _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; @@ -3689,1933 +3871,1833 @@ function dispatchEvent(target, topLevelType, nativeEvent) { // where it would do it. } -// can re-export everything from this module. +// This module only exists as an ESM wrapper around the external CommonJS +var scheduleCallback = Scheduler.unstable_scheduleCallback; +var cancelCallback = Scheduler.unstable_cancelCallback; +var shouldYield = Scheduler.unstable_shouldYield; +var requestPaint = Scheduler.unstable_requestPaint; +var now = Scheduler.unstable_now; +var ImmediatePriority = Scheduler.unstable_ImmediatePriority; +var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var NormalPriority = Scheduler.unstable_NormalPriority; +var IdlePriority = Scheduler.unstable_IdlePriority; -function shim() { - { - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; } -} // Mutation (when unsupported) - -var supportsMutation = false; -var commitMount = shim; -var clearContainer = shim; -// can re-export everything from this module. + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; -function shim$1() { - { - throw Error( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." - ); + 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; } -} // Hydration (when unsupported) -var isSuspenseInstancePending = shim$1; -var isSuspenseInstanceFallback = shim$1; -var hydrateTextInstance = shim$1; - -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, - cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage.createChildSet, - appendChildNode = _nativeFabricUIManage.appendChild, - appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, - completeRoot = _nativeFabricUIManage.completeRoot, - registerEventHandler = _nativeFabricUIManage.registerEventHandler, - fabricMeasure = _nativeFabricUIManage.measure, - fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, - fabricMeasureLayout = _nativeFabricUIManage.measureLayout; -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. -// % 10 === 1 means it is a rootTag. -// % 2 === 0 means it is a Fabric tag. -// This means that they never overlap. - -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. - */ + if (!hook.supportsFiber) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. -var ReactFabricHostComponent = /*#__PURE__*/ (function() { - function ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ) { - this._nativeTag = tag; - this.viewConfig = viewConfig; - this.currentProps = props; - this._internalInstanceHandle = internalInstanceHandle; + return true; } - var _proto = ReactFabricHostComponent.prototype; - - _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists - _proto.measure = function measure(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - - _proto.measureInWindow = function measureInWindow(callback) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - - _proto.measureLayout = function measureLayout( - relativeToNativeNode, - onSuccess, - onFail - ) /* currently unused */ + return true; +} +function onScheduleRoot(root, children) { { if ( - typeof relativeToNativeNode === "number" || - !(relativeToNativeNode instanceof ReactFabricHostComponent) + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" ) { - { - error( - "Warning: ref.measureLayout must be called with a ref to a native component." - ); - } + try { + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; - return; + error("React instrumentation encountered an error: %s", err); + } + } } + } +} +function onCommitRoot(root, eventPriority) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; + if (enableProfilerTimer) { + var schedulerPriority; - _proto.setNativeProps = function setNativeProps(nativeProps) { - { - error("Warning: setNativeProps is not currently supported in Fabric"); - } + switch (eventPriority) { + case DiscreteEventPriority: + schedulerPriority = ImmediatePriority; + break; - return; - }; + case ContinuousEventPriority: + schedulerPriority = UserBlockingPriority; + break; - return ReactFabricHostComponent; -})(); // eslint-disable-next-line no-unused-expressions -function appendInitialChild(parentInstance, child) { - appendChildNode(parentInstance.node, child.node); -} -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = nextReactTag; - nextReactTag += 2; - var viewConfig = getViewConfigForType(type); + case DefaultEventPriority: + schedulerPriority = NormalPriority; + break; - { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] + case IdleEventPriority: + schedulerPriority = IdlePriority; + break; + + default: + schedulerPriority = NormalPriority; + break; + } + + injectedHook.onCommitFiberRoot( + rendererID, + root, + schedulerPriority, + didError ); + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } } - - var updatePayload = create(props, viewConfig.validAttributes); - var node = createNode( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload, // props - internalInstanceHandle // internalInstanceHandle - ); - var component = new ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ); - return { - node: node, - canonical: component - }; } -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - if (!hostContext.isInAParentText) { - throw Error("Text strings must be rendered within a component."); - } +function onPostCommitRoot(root) { + if ( + injectedHook && + typeof injectedHook.onPostCommitFiberRoot === "function" + ) { + try { + injectedHook.onPostCommitFiberRoot(rendererID, root); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; - var tag = nextReactTag; - nextReactTag += 2; - var node = createNode( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { - text: text - }, // props - internalInstanceHandle // instance handle - ); - return { - node: node - }; -} -function getRootHostContext(rootContainerInstance) { - return { - isInAParentText: false - }; + error("React instrumentation encountered an error: %s", err); + } + } + } + } } -function getChildHostContext(parentHostContext, type, rootContainerInstance) { - var prevIsInAParentText = parentHostContext.isInAParentText; - var isInAParentText = - type === "AndroidTextInput" || // Android - type === "RCTMultilineTextInputView" || // iOS - type === "RCTSinglelineTextInputView" || // iOS - type === "RCTText" || - type === "RCTVirtualText"; +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; - if (prevIsInAParentText !== isInAParentText) { - return { - isInAParentText: isInAParentText - }; - } else { - return parentHostContext; + error("React instrumentation encountered an error: %s", err); + } + } + } } } -function getPublicInstance(instance) { - return instance.canonical; -} -function prepareForCommit(containerInfo) { - // Noop - return null; -} -function prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - hostContext -) { - var viewConfig = instance.canonical.viewConfig; - var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // TODO: If the event handlers have changed, we need to update the current props - // in the commit phase but there is no host config hook to do it yet. - // So instead we hack it by updating it in the render phase. - instance.canonical.currentProps = newProps; - return updatePayload; -} -function resetAfterCommit(containerInfo) { - // Noop -} -function shouldSetTextContent(type, props) { - // TODO (bvaughn) Revisit this decision. - // Always returning false simplifies the createInstance() implementation, - // But creates an additional child Fiber for raw text children. - // No additional native views are created though. - // It's not clear to me which is better so I'm deferring for now. - // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 - return false; -} // The Fabric renderer is secondary to the existing React Native renderer. -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; // ------------------- -function cloneInstance( - instance, - updatePayload, - type, - oldProps, - newProps, - internalInstanceHandle, - keepChildren, - recyclableInstance -) { - var node = instance.node; - var clone; +var NoMode = + /* */ + 0; // TODO: Remove ConcurrentMode by reading from the root tag instead - 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); - } - } +var ConcurrentMode = + /* */ + 1; +var ProfileMode = + /* */ + 2; +var DebugTracingMode = + /* */ + 4; +var StrictLegacyMode = + /* */ + 8; +var StrictEffectsMode = + /* */ + 16; - return { - node: clone, - canonical: instance.canonical - }; -} -function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { - var viewConfig = instance.canonical.viewConfig; - var node = instance.node; - var updatePayload = create( - { - style: { - display: "none" - } - }, - viewConfig.validAttributes - ); - return { - node: cloneNodeWithNewProps(node, updatePayload), - canonical: instance.canonical - }; -} -function cloneHiddenTextInstance(instance, text, internalInstanceHandle) { - throw new Error("Not yet implemented."); -} -function createContainerChildSet(container) { - return createChildNodeSet(container); -} -function appendChildToContainerChildSet(childSet, child) { - appendChildNodeToSet(childSet, child.node); -} -function finalizeContainerChildren(container, newChildren) { - completeRoot(container, newChildren); -} -function makeClientIdInDEV(warnOnAccessInDEV) { - throw new Error("Not yet implemented"); -} -function preparePortalMount(portalInstance) { - // noop -} +// If those values are changed that package should be rebuilt and redeployed. -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -function describeBuiltInComponentFrame(name, source, ownerFn) { - { - var ownerName = null; +var TotalLanes = 31; +var NoLanes = + /* */ + 0; +var NoLane = + /* */ + 0; +var SyncLane = + /* */ + 1; +var InputContinuousHydrationLane = + /* */ + 2; +var InputContinuousLane = + /* */ + 4; +var DefaultHydrationLane = + /* */ + 8; +var DefaultLane = + /* */ + 16; +var TransitionHydrationLane = + /* */ + 32; +var TransitionLanes = + /* */ + 4194240; +var TransitionLane1 = + /* */ + 64; +var TransitionLane2 = + /* */ + 128; +var TransitionLane3 = + /* */ + 256; +var TransitionLane4 = + /* */ + 512; +var TransitionLane5 = + /* */ + 1024; +var TransitionLane6 = + /* */ + 2048; +var TransitionLane7 = + /* */ + 4096; +var TransitionLane8 = + /* */ + 8192; +var TransitionLane9 = + /* */ + 16384; +var TransitionLane10 = + /* */ + 32768; +var TransitionLane11 = + /* */ + 65536; +var TransitionLane12 = + /* */ + 131072; +var TransitionLane13 = + /* */ + 262144; +var TransitionLane14 = + /* */ + 524288; +var TransitionLane15 = + /* */ + 1048576; +var TransitionLane16 = + /* */ + 2097152; +var RetryLanes = + /* */ + 130023424; +var RetryLane1 = + /* */ + 4194304; +var RetryLane2 = + /* */ + 8388608; +var RetryLane3 = + /* */ + 16777216; +var RetryLane4 = + /* */ + 33554432; +var RetryLane5 = + /* */ + 67108864; +var SomeRetryLane = RetryLane1; +var SelectiveHydrationLane = + /* */ + 134217728; +var NonIdleLanes = + /* */ + 268435455; +var IdleHydrationLane = + /* */ + 268435456; +var IdleLane = + /* */ + 536870912; +var OffscreenLane = + /* */ + 1073741824; // This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler) +var NoTimestamp = -1; +var nextTransitionLane = TransitionLane1; +var nextRetryLane = RetryLane1; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } +function getHighestPriorityLanes(lanes) { + switch (getHighestPriorityLane(lanes)) { + case SyncLane: + return SyncLane; - return describeComponentFrame(name, source, ownerName); + case InputContinuousHydrationLane: + return InputContinuousHydrationLane; + + case InputContinuousLane: + return InputContinuousLane; + + case DefaultHydrationLane: + return DefaultHydrationLane; + + case DefaultLane: + return DefaultLane; + + case TransitionHydrationLane: + return TransitionHydrationLane; + + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + case TransitionLane15: + case TransitionLane16: + return lanes & TransitionLanes; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + case RetryLane5: + return lanes & RetryLanes; + + case SelectiveHydrationLane: + return SelectiveHydrationLane; + + case IdleHydrationLane: + return IdleHydrationLane; + + case IdleLane: + return IdleLane; + + case OffscreenLane: + return OffscreenLane; + + default: + { + error("Should have found matching lanes. This is a bug in React."); + } // This shouldn't be reachable, but as a fallback, return the entire bitmask. + + return lanes; } } -var componentFrameCache; -{ - var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap(); -} -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; -function describeComponentFrame(name, source, ownerName) { - var sourceInfo = ""; + if (pendingLanes === NoLanes) { + return NoLanes; + } - if (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: - // prefer "folder/index.js" instead of just "index.js". + var nextLanes = NoLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished, + // even if the work is suspended. - if (/^index\./.test(fileName)) { - var match = path.match(BEFORE_SLASH_RE); + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - if (match) { - var pathBeforeSlash = match[1]; + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; + + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); } } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + } + } } - return "\n in " + (name || "Unknown") + sourceInfo; -} + if (nextLanes === NoLanes) { + // This should only be reachable if we're suspended + // TODO: Consider warning in this path if a fallback timer is not scheduled. + return NoLanes; + } // If we're already in the middle of a render, switching lanes will interrupt + // it and we'll lose our progress. We should only do this if the new lanes are + // higher priority. -function describeClassComponentFrame(ctor, source, ownerFn) { - { - return describeFunctionComponentFrame(ctor, source, ownerFn); - } -} -function describeFunctionComponentFrame(fn, source, ownerFn) { - { - if (!fn) { - return ""; + if ( + wipLanes !== NoLanes && + wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't + // bother waiting until the root is complete. + (wipLanes & suspendedLanes) === NoLanes + ) { + var nextLane = getHighestPriorityLane(nextLanes); + var wipLane = getHighestPriorityLane(wipLanes); + + if ( + // Tests whether the next lane is equal or lower priority than the wip + // one. This works because the bits decrease in priority as you go left. + nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The + // only difference between default updates and transition updates is that + // default updates do not support refresh transitions. + (nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) + ) { + // Keep working on the existing in-progress tree. Do not interrupt. + return wipLanes; } + } - var name = fn.displayName || fn.name || null; - var ownerName = null; + if ((nextLanes & InputContinuousLane) !== NoLanes) { + // When updates are sync by default, we entangle continuous priority updates + // and default updates, so they render in the same batch. The only reason + // they use separate lanes is because continuous updates should interrupt + // transitions, but default updates should not. + nextLanes |= pendingLanes & DefaultLane; + } // Check for entangled lanes and add them to the batch. + // + // A lane is said to be entangled with another when it's not allowed to render + // in a batch that does not also include the other lane. Typically we do this + // when multiple updates have the same source, and we only want to respond to + // the most recent event from that source. + // + // Note that we apply entanglements *after* checking for partial work above. + // This means that if a lane is entangled during an interleaved event while + // it's already rendering, we won't interrupt it. This is intentional, since + // entanglement is usually "best effort": we'll try our best to render the + // lanes in the same batch, but it's not worth throwing out partially + // completed work in order to do it. + // TODO: Reconsider this. The counter-argument is that the partial work + // represents an intermediate state, which we don't want to show to the user. + // And by spending extra time finishing it, we're increasing the amount of + // time it takes to show the final state, which is what they are actually + // waiting for. + // + // For those exceptions where entanglement is semantically important, like + // useMutableSource, we should ensure that there is no partial work at the + // time we apply the entanglement. - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + var entangledLanes = root.entangledLanes; - return describeComponentFrame(name, source, ownerName); + if (entangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = nextLanes & entangledLanes; + + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + nextLanes |= entanglements[index]; + lanes &= ~lane; + } } + + return nextLanes; } +function getMostRecentEventTime(root, lanes) { + var eventTimes = root.eventTimes; + var mostRecentEventTime = NoTimestamp; -function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { - if (type == null) { - return ""; - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var eventTime = eventTimes[index]; - if (typeof type === "function") { - { - return describeFunctionComponentFrame(type, source, ownerFn); + if (eventTime > mostRecentEventTime) { + mostRecentEventTime = eventTime; } - } - if (typeof type === "string") { - return describeBuiltInComponentFrame(type, source, ownerFn); + lanes &= ~lane; } - switch (type) { - case REACT_SUSPENSE_TYPE: - return describeBuiltInComponentFrame("Suspense", source, ownerFn); + return mostRecentEventTime; +} - case REACT_SUSPENSE_LIST_TYPE: - return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); - } +function computeExpirationTime(lane, currentTime) { + switch (lane) { + case SyncLane: + case InputContinuousHydrationLane: + case InputContinuousLane: + // User interactions should expire slightly more quickly. + // + // NOTE: This is set to the corresponding constant as in Scheduler.js. + // When we made it larger, a product metric in www regressed, suggesting + // there's a user interaction that's being starved by a series of + // synchronous updates. If that theory is correct, the proper solution is + // to fix the starvation. However, this scenario supports the idea that + // expiration times are an important safeguard when starvation + // does happen. + return currentTime + 250; + + case DefaultHydrationLane: + case DefaultLane: + case TransitionHydrationLane: + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + case TransitionLane15: + case TransitionLane16: + return currentTime + 5000; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + case RetryLane5: + // TODO: Retries should be allowed to expire if they are CPU bound for + // too long, but when I made this change it caused a spike in browser + // crashes. There must be some other underlying bug; not super urgent but + // ideally should figure out why and fix it. Unfortunately we don't have + // a repro for the crashes, only detected via production metrics. + return NoTimestamp; + + case SelectiveHydrationLane: + case IdleHydrationLane: + case IdleLane: + case OffscreenLane: + // Anything idle priority or lower should never expire. + return NoTimestamp; - if (typeof type === "object") { - switch (type.$$typeof) { - case REACT_FORWARD_REF_TYPE: - return describeFunctionComponentFrame(type.render, source, ownerFn); + default: + { + error("Should have found matching lanes. This is a bug in React."); + } - case REACT_MEMO_TYPE: - // Memo may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); - - case REACT_LAZY_TYPE: { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; - - try { - // Lazy may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV( - init(payload), - source, - ownerFn - ); - } catch (x) {} - } - } - } - - return ""; -} - -var loggedTypeFailures = {}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - -function setCurrentlyValidatingElement(element) { - { - if (element) { - var owner = element._owner; - var stack = describeUnknownElementTypeFrameInDEV( - element.type, - element._source, - owner ? owner.type : null - ); - ReactDebugCurrentFrame.setExtraStackFrame(stack); - } else { - ReactDebugCurrentFrame.setExtraStackFrame(null); - } + return NoTimestamp; } } -function checkPropTypes(typeSpecs, values, location, componentName, element) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); - - for (var typeSpecName in typeSpecs) { - if (has(typeSpecs, typeSpecName)) { - var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - if (typeof typeSpecs[typeSpecName] !== "function") { - var err = Error( - (componentName || "React class") + - ": " + - location + - " type `" + - typeSpecName + - "` is invalid; " + - "it must be a function, usually from the `prop-types` package, but received `" + - typeof typeSpecs[typeSpecName] + - "`." + - "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." - ); - err.name = "Invariant Violation"; - throw err; - } - - error$1 = typeSpecs[typeSpecName]( - values, - typeSpecName, - componentName, - location, - null, - "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" - ); - } catch (ex) { - error$1 = ex; - } +function markStarvedLanesAsExpired(root, currentTime) { + // TODO: This gets called every time we yield. We can optimize by storing + // the earliest expiration time on the root. Then use that to quickly bail out + // of this function. + var pendingLanes = root.pendingLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; + var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their + // expiration time. If so, we'll assume the update is being starved and mark + // it as expired to force it to finish. - if (error$1 && !(error$1 instanceof Error)) { - setCurrentlyValidatingElement(element); + var lanes = pendingLanes; - error( - "%s: type specification of %s" + - " `%s` is invalid; the type checker " + - "function must return `null` or an `Error` but returned a %s. " + - "You may have forgotten to pass an argument to the type checker " + - "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + - "shape all require an argument).", - componentName || "React class", - location, - typeSpecName, - typeof error$1 - ); + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; - setCurrentlyValidatingElement(null); - } + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); + } + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; + } - if ( - error$1 instanceof Error && - !(error$1.message in loggedTypeFailures) - ) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error$1.message] = true; - setCurrentlyValidatingElement(element); + lanes &= ~lane; + } +} // This returns the highest priority pending lanes regardless of whether they +function getLanesToRetrySynchronouslyOnError(root) { + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - error("Failed %s type: %s", location, error$1.message); + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } - setCurrentlyValidatingElement(null); - } - } - } + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } -} -var valueStack = []; -var fiberStack; + return NoLanes; +} +function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; +} +function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; +} +function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; +} +function shouldTimeSlice(root, lanes) { + if ((lanes & root.expiredLanes) !== NoLanes) { + // At least one of these lanes expired. To prevent additional starvation, + // finish rendering without yielding execution. + return false; + } -{ - fiberStack = []; + var SyncDefaultLanes = + InputContinuousHydrationLane | + InputContinuousLane | + DefaultHydrationLane | + DefaultLane; + return (lanes & SyncDefaultLanes) === NoLanes; } +function isTransitionLane(lane) { + return (lane & TransitionLanes) !== 0; +} +function claimNextTransitionLane() { + // Cycle through the lanes, assigning each new transition to the next lane. + // In most cases, this means every transition gets its own lane, until we + // run out of lanes and cycle back to the beginning. + var lane = nextTransitionLane; + nextTransitionLane <<= 1; -var index = -1; + if ((nextTransitionLane & TransitionLanes) === 0) { + nextTransitionLane = TransitionLane1; + } -function createCursor(defaultValue) { - return { - current: defaultValue - }; + return lane; } +function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; -function pop(cursor, fiber) { - if (index < 0) { - { - error("Unexpected pop."); - } - - return; + if ((nextRetryLane & RetryLanes) === 0) { + nextRetryLane = RetryLane1; } - { - if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); - } - } + return lane; +} +function getHighestPriorityLane(lanes) { + return lanes & -lanes; +} +function pickArbitraryLane(lanes) { + // This wrapper function gets inlined. Only exists so to communicate that it + // doesn't matter which bit is selected; you can pick any bit without + // affecting the algorithms where its used. Here I'm using + // getHighestPriorityLane because it requires the fewest operations. + return getHighestPriorityLane(lanes); +} - cursor.current = valueStack[index]; - valueStack[index] = null; +function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); +} - { - fiberStack[index] = null; - } +function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); +} - index--; +function includesSomeLane(a, b) { + return (a & b) !== NoLanes; +} +function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; +} +function mergeLanes(a, b) { + return a | b; } +function removeLanes(set, subset) { + return set & ~subset; +} +function intersectLanes(a, b) { + return a & b; +} // Seems redundant, but it changes the type from a single lane (used for +// updates) to a group of lanes (used for flushing work). -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; +function laneToLanes(lane) { + return lane; +} +function createLaneMap(initial) { + // Intentionally pushing one by one. + // https://v8.dev/blog/elements-kinds#avoid-creating-holes + var laneMap = []; - { - fiberStack[index] = fiber; + for (var i = 0; i < TotalLanes; i++) { + laneMap.push(initial); } - cursor.current = value; + return laneMap; } +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update + // could unblock them. Clear the suspended lanes so that we can try rendering + // them again. + // + // TODO: We really only need to unsuspend only lanes that are in the + // `subtreeLanes` of the updated fiber, or the update lanes of the return + // path. This would exclude suspended updates in an unrelated sibling tree, + // since there's no way for this update to unblock it. + // + // We don't do this if the incoming update is idle, because we never process + // idle updates until after all the regular updates have finished; there's no + // way it could unblock a transition. -var warnedAboutMissingGetChildContext; + if (updateLane !== IdleLane) { + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; + } -{ - warnedAboutMissingGetChildContext = {}; + var eventTimes = root.eventTimes; + var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most + // recent event, and we assume time is monotonically increasing. + + eventTimes[index] = eventTime; } +function markRootSuspended(root, suspendedLanes) { + root.suspendedLanes |= suspendedLanes; + root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. -var emptyContextObject = {}; - -{ - Object.freeze(emptyContextObject); -} // A cursor to the current merged context object on the stack. - -var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. + var expirationTimes = root.expirationTimes; + var lanes = suspendedLanes; -var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. -// We use this to get access to the parent context after we have already -// pushed the next context provider, and now need to merge their contexts. + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; + } +} +function markRootPinged(root, pingedLanes, eventTime) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; +} +function markRootMutableRead(root, updateLane) { + root.mutableReadLanes |= updateLane & root.pendingLanes; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again -var previousContext = emptyContextObject; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; -function getUnmaskedContext( - workInProgress, - Component, - didPushOwnContextIfProvider -) { - { - if (didPushOwnContextIfProvider && isContextProvider(Component)) { - // If the fiber is a context provider itself, when we read its context - // we may have already pushed its own child context on the stack. A context - // provider should not "see" its own child context. Therefore we read the - // previous (parent) context instead for a context provider. - return previousContext; - } + var entanglements = root.entanglements; + var eventTimes = root.eventTimes; + var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work - return contextStackCursor.current; - } -} + var lanes = noLongerPendingLanes; -function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { - var instance = workInProgress.stateNode; - instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; - instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + eventTimes[index] = NoTimestamp; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } +function markRootEntangled(root, entangledLanes) { + // In addition to entangling each of the given lanes with each other, we also + // have to consider _transitive_ entanglements. For each lane that is already + // entangled with *any* of the given lanes, that lane is now transitively + // entangled with *all* the given lanes. + // + // Translated: If C is entangled with A, then entangling A with B also + // entangles C with B. + // + // If this is hard to grasp, it might help to intentionally break this + // function and look at the tests that fail in ReactTransition-test.js. Try + // commenting out one of the conditions below. + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + var entanglements = root.entanglements; + var lanes = rootEntangledLanes; -function getMaskedContext(workInProgress, unmaskedContext) { - { - var type = workInProgress.type; - var contextTypes = type.contextTypes; - - if (!contextTypes) { - return emptyContextObject; - } // Avoid recreating masked context unless unmasked context has changed. - // Failing to do this will result in unnecessary calls to componentWillReceiveProps. - // This may trigger infinite loops if componentWillReceiveProps calls setState. - - var instance = workInProgress.stateNode; + while (lanes) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + // Is this one of the newly entangled lanes? + (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? + (entanglements[index] & entangledLanes) ) { - return instance.__reactInternalMemoizedMaskedChildContext; + entanglements[index] |= entangledLanes; } - var context = {}; + lanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. +// Based on: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 - for (var key in contextTypes) { - context[key] = unmaskedContext[key]; - } +var log = Math.log; +var LN2 = Math.LN2; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); - } // Cache unmasked context so we can avoid recreating masked context unless necessary. - // Context is created before the class component is instantiated so check for instance. +function clz32Fallback(lanes) { + if (lanes === 0) { + return 32; + } - if (instance) { - cacheContext(workInProgress, unmaskedContext, context); - } + return (31 - ((log(lanes) / LN2) | 0)) | 0; +} - return context; - } +var DiscreteEventPriority = SyncLane; +var ContinuousEventPriority = InputContinuousLane; +var DefaultEventPriority = DefaultLane; +var IdleEventPriority = IdleLane; +var currentUpdatePriority = NoLane; +function getCurrentUpdatePriority() { + return currentUpdatePriority; +} +function setCurrentUpdatePriority(newPriority) { + currentUpdatePriority = newPriority; +} +function higherEventPriority(a, b) { + return a !== 0 && a < b ? a : b; } +function lowerEventPriority(a, b) { + return a === 0 || a > b ? a : b; +} +function isHigherEventPriority(a, b) { + return a !== 0 && a < b; +} +function lanesToEventPriority(lanes) { + var lane = getHighestPriorityLane(lanes); -function hasContextChanged() { - { - return didPerformWorkStackCursor.current; + if (!isHigherEventPriority(DiscreteEventPriority, lane)) { + return DiscreteEventPriority; } -} -function isContextProvider(type) { - { - var childContextTypes = type.childContextTypes; - return childContextTypes !== null && childContextTypes !== undefined; + if (!isHigherEventPriority(ContinuousEventPriority, lane)) { + return ContinuousEventPriority; } -} -function popContext(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); + if (includesNonIdleWork(lane)) { + return DefaultEventPriority; } + + return IdleEventPriority; } -function popTopLevelContextObject(fiber) { +// can re-export everything from this module. + +function shim() { { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); } -} +} // Mutation (when unsupported) -function pushTopLevelContextObject(fiber, context, didChange) { - { - if (!(contextStackCursor.current === emptyContextObject)) { - throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." - ); - } +var supportsMutation = false; +var commitMount = shim; +var clearContainer = shim; - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); - } -} +// can re-export everything from this module. -function processChildContext(fiber, type, parentContext) { +function shim$1() { { - var instance = fiber.stateNode; - var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. - // It has only been added in Fiber to match the (unintentional) behavior in Stack. - - if (typeof instance.getChildContext !== "function") { - { - var componentName = getComponentName(type) || "Unknown"; + throw Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ); + } +} // Hydration (when unsupported) +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var hydrateTextInstance = shim$1; +var errorHydratingContainer = shim$1; - if (!warnedAboutMissingGetChildContext[componentName]) { - warnedAboutMissingGetChildContext[componentName] = true; +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, + cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout; +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. +// This means that they never overlap. - error( - "%s.childContextTypes is specified but there is no getChildContext() method " + - "on the instance. You can either define getChildContext() on %s or remove " + - "childContextTypes from it.", - componentName, - componentName - ); - } - } +var nextReactTag = 2; - return parentContext; - } +// 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 childContext = instance.getChildContext(); +var ReactFabricHostComponent = /*#__PURE__*/ (function() { + function ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle + ) { + this._nativeTag = tag; + this.viewConfig = viewConfig; + this.currentProps = props; + this._internalInstanceHandle = internalInstanceHandle; + } - for (var contextKey in childContext) { - if (!(contextKey in childContextTypes)) { - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' - ); - } - } + var _proto = ReactFabricHostComponent.prototype; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); - } + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; - return Object.assign({}, parentContext, childContext); - } -} + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; -function pushContextProvider(workInProgress) { - { - var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. - // If the instance does not exist yet, we will push null at first, - // and replace it on the stack later when invalidating the context. - - var memoizedMergedChildContext = - (instance && instance.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; // Remember the parent context so we can merge with it later. - // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + _proto.measure = function measure(callback) { + fabricMeasure( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; - previousContext = contextStackCursor.current; - push(contextStackCursor, memoizedMergedChildContext, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress + _proto.measureInWindow = function measureInWindow(callback) { + fabricMeasureInWindow( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - return true; - } -} + }; -function invalidateContextProvider(workInProgress, type, didChange) { + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) /* currently unused */ { - var instance = workInProgress.stateNode; + if ( + typeof relativeToNativeNode === "number" || + !(relativeToNativeNode instanceof ReactFabricHostComponent) + ) { + { + error( + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + } - if (!instance) { - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); + return; } - if (didChange) { - // Merge parent and own context. - // Skip this if we're not updating due to sCU. - // This avoids unnecessarily recomputing memoized values. - var mergedContext = processChildContext( - workInProgress, - type, - previousContext - ); - instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. - // It is important to unwind the context in the reverse order. - - pop(didPerformWorkStackCursor, workInProgress); - pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. - - push(contextStackCursor, mergedContext, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } else { - pop(didPerformWorkStackCursor, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } - } -} + fabricMeasureLayout( + this._internalInstanceHandle.stateNode.node, + relativeToNativeNode._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; -function findCurrentUnmaskedContext(fiber) { - { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw Error( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." - ); + _proto.setNativeProps = function setNativeProps(nativeProps) { + { + error("Warning: setNativeProps is not currently supported in Fabric"); } - var node = fiber; - - do { - switch (node.tag) { - case HostRoot: - return node.stateNode.context; - - case ClassComponent: { - var Component = node.type; + return; + }; - if (isContextProvider(Component)) { - return node.stateNode.__reactInternalMemoizedMergedChildContext; - } + return ReactFabricHostComponent; +})(); // eslint-disable-next-line no-unused-expressions +function appendInitialChild(parentInstance, child) { + appendChildNode(parentInstance.node, child.node); +} +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + var tag = nextReactTag; + nextReactTag += 2; + var viewConfig = getViewConfigForType(type); - break; - } + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] + ); } - - node = node.return; - } while (node !== null); - - { - throw Error( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); } } -} - -var LegacyRoot = 0; -var BlockingRoot = 1; -var ConcurrentRoot = 2; -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; - } - - 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) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. - - return true; + var updatePayload = create(props, viewConfig.validAttributes); + var node = createNode( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload, // props + internalInstanceHandle // internalInstanceHandle + ); + var component = new ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle + ); + return { + node: node, + canonical: component + }; +} +function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + if (!hostContext.isInAParentText) { + throw Error("Text strings must be rendered within a component."); } - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. + var tag = nextReactTag; + nextReactTag += 2; + var node = createNode( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists - - return true; + text: text + }, // props + internalInstanceHandle // instance handle + ); + return { + node: node + }; } -function onScheduleRoot(root, children) { - { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } +function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; } -function onCommitRoot(root, priorityLevel) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; - - if (enableProfilerTimer) { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; +function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; - error("React instrumentation encountered an error: %s", err); - } - } - } + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText + }; + } else { + return parentHostContext; } } -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } +function getPublicInstance(instance) { + return instance.canonical; } - -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_now = Scheduler.unstable_now; - -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); - } +function prepareForCommit(containerInfo) { + // Noop + return null; } -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. - -var ImmediatePriority = 99; -var UserBlockingPriority = 98; -var NormalPriority = 97; -var LowPriority = 96; -var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - -var NoPriority = 90; -var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. - -var SyncLanePriority = 15; -var SyncBatchedLanePriority = 14; -var InputDiscreteHydrationLanePriority = 13; -var InputDiscreteLanePriority = 12; -var InputContinuousHydrationLanePriority = 11; -var InputContinuousLanePriority = 10; -var DefaultHydrationLanePriority = 9; -var DefaultLanePriority = 8; -var TransitionHydrationPriority = 7; -var TransitionPriority = 6; -var RetryLanePriority = 5; -var SelectiveHydrationLanePriority = 4; -var IdleHydrationLanePriority = 3; -var IdleLanePriority = 2; -var OffscreenLanePriority = 1; -var NoLanePriority = 0; -var TotalLanes = 31; -var NoLanes = - /* */ - 0; -var NoLane = - /* */ - 0; -var SyncLane = - /* */ - 1; -var SyncBatchedLane = - /* */ - 2; -var InputDiscreteHydrationLane = - /* */ - 4; -var InputDiscreteLanes = - /* */ - 24; -var InputContinuousHydrationLane = - /* */ - 32; -var InputContinuousLanes = - /* */ - 192; -var DefaultHydrationLane = - /* */ - 256; -var DefaultLanes = - /* */ - 3584; -var TransitionHydrationLane = - /* */ - 4096; -var TransitionLanes = - /* */ - 4186112; -var RetryLanes = - /* */ - 62914560; -var SomeRetryLane = - /* */ - 33554432; -var SelectiveHydrationLane = - /* */ - 67108864; -var NonIdleLanes = - /* */ - 134217727; -var IdleHydrationLane = - /* */ - 134217728; -var IdleLanes = - /* */ - 805306368; -var OffscreenLane = - /* */ - 1073741824; -var NoTimestamp = -1; -// Used by getHighestPriorityLanes and getNextLanes: +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. -var return_highestLanePriority = DefaultLanePriority; + instance.canonical.currentProps = newProps; + return updatePayload; +} +function resetAfterCommit(containerInfo) { + // Noop +} +function shouldSetTextContent(type, props) { + // TODO (bvaughn) Revisit this decision. + // Always returning false simplifies the createInstance() implementation, + // But creates an additional child Fiber for raw text children. + // No additional native views are created though. + // It's not clear to me which is better so I'm deferring for now. + // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 + return false; +} +function getCurrentEventPriority() { + return DefaultEventPriority; +} // The Fabric renderer is secondary to the existing React Native renderer. +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; // ------------------- +function cloneInstance( + instance, + updatePayload, + type, + oldProps, + newProps, + internalInstanceHandle, + keepChildren, + recyclableInstance +) { + var node = instance.node; + var clone; -function getHighestPriorityLanes(lanes) { - if ((SyncLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncLanePriority; - return SyncLane; + 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 ((SyncBatchedLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncBatchedLanePriority; - return SyncBatchedLane; - } + return { + node: clone, + canonical: instance.canonical + }; +} +function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { + var viewConfig = instance.canonical.viewConfig; + var node = instance.node; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes + ); + return { + node: cloneNodeWithNewProps(node, updatePayload), + canonical: instance.canonical + }; +} +function cloneHiddenTextInstance(instance, text, internalInstanceHandle) { + throw new Error("Not yet implemented."); +} +function createContainerChildSet(container) { + return createChildNodeSet(container); +} +function appendChildToContainerChildSet(childSet, child) { + appendChildNodeToSet(childSet, child.node); +} +function finalizeContainerChildren(container, newChildren) { + completeRoot(container, newChildren); +} +function makeClientIdInDEV(warnOnAccessInDEV) { + throw new Error("Not yet implemented"); +} +function preparePortalMount(portalInstance) { + // noop +} - if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { - return_highestLanePriority = InputDiscreteHydrationLanePriority; - return InputDiscreteHydrationLane; - } +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +function describeBuiltInComponentFrame(name, source, ownerFn) { + { + var ownerName = null; - var inputDiscreteLanes = InputDiscreteLanes & lanes; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - if (inputDiscreteLanes !== NoLanes) { - return_highestLanePriority = InputDiscreteLanePriority; - return inputDiscreteLanes; + return describeComponentFrame(name, source, ownerName); } +} +var componentFrameCache; - if ((lanes & InputContinuousHydrationLane) !== NoLanes) { - return_highestLanePriority = InputContinuousHydrationLanePriority; - return InputContinuousHydrationLane; - } +{ + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; - var inputContinuousLanes = InputContinuousLanes & lanes; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; - if (inputContinuousLanes !== NoLanes) { - return_highestLanePriority = InputContinuousLanePriority; - return inputContinuousLanes; - } + 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 ((lanes & DefaultHydrationLane) !== NoLanes) { - return_highestLanePriority = DefaultHydrationLanePriority; - return DefaultHydrationLane; - } + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); - var defaultLanes = DefaultLanes & lanes; + if (match) { + var pathBeforeSlash = match[1]; - if (defaultLanes !== NoLanes) { - return_highestLanePriority = DefaultLanePriority; - return defaultLanes; - } + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } + } + } - if ((lanes & TransitionHydrationLane) !== NoLanes) { - return_highestLanePriority = TransitionHydrationPriority; - return TransitionHydrationLane; + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } - var transitionLanes = TransitionLanes & lanes; + return "\n in " + (name || "Unknown") + sourceInfo; +} - if (transitionLanes !== NoLanes) { - return_highestLanePriority = TransitionPriority; - return transitionLanes; +function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeFunctionComponentFrame(ctor, source, ownerFn); } +} +function describeFunctionComponentFrame(fn, source, ownerFn) { + { + if (!fn) { + return ""; + } - var retryLanes = RetryLanes & lanes; + var name = fn.displayName || fn.name || null; + var ownerName = null; - if (retryLanes !== NoLanes) { - return_highestLanePriority = RetryLanePriority; - return retryLanes; - } + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - if (lanes & SelectiveHydrationLane) { - return_highestLanePriority = SelectiveHydrationLanePriority; - return SelectiveHydrationLane; + return describeComponentFrame(name, source, ownerName); } +} - if ((lanes & IdleHydrationLane) !== NoLanes) { - return_highestLanePriority = IdleHydrationLanePriority; - return IdleHydrationLane; +function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; } - var idleLanes = IdleLanes & lanes; - - if (idleLanes !== NoLanes) { - return_highestLanePriority = IdleLanePriority; - return idleLanes; + if (typeof type === "function") { + { + return describeFunctionComponentFrame(type, source, ownerFn); + } } - if ((OffscreenLane & lanes) !== NoLanes) { - return_highestLanePriority = OffscreenLanePriority; - return OffscreenLane; + if (typeof type === "string") { + return describeBuiltInComponentFrame(type, source, ownerFn); } - { - error("Should have found matching lanes. This is a bug in React."); - } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - - return_highestLanePriority = DefaultLanePriority; - return lanes; -} - -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case ImmediatePriority: - return SyncLanePriority; - - case UserBlockingPriority: - return InputContinuousLanePriority; - - case NormalPriority: - case LowPriority: - // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. - return DefaultLanePriority; - - case IdlePriority: - return IdleLanePriority; + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense", source, ownerFn); - default: - return NoLanePriority; + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case SyncLanePriority: - case SyncBatchedLanePriority: - return ImmediatePriority; - case InputDiscreteHydrationLanePriority: - case InputDiscreteLanePriority: - case InputContinuousHydrationLanePriority: - case InputContinuousLanePriority: - return UserBlockingPriority; - - case DefaultHydrationLanePriority: - case DefaultLanePriority: - case TransitionHydrationPriority: - case TransitionPriority: - case SelectiveHydrationLanePriority: - case RetryLanePriority: - return NormalPriority; + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render, source, ownerFn); - case IdleHydrationLanePriority: - case IdleLanePriority: - case OffscreenLanePriority: - return IdlePriority; + case REACT_MEMO_TYPE: + // Memo may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); - case NoLanePriority: - return NoPriority; + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; - default: { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); + try { + // Lazy may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV( + init(payload), + source, + ownerFn + ); + } catch (x) {} + } } } -} -function getNextLanes(root, wipLanes) { - // Early bailout if there's no pending work left. - var pendingLanes = root.pendingLanes; - - if (pendingLanes === NoLanes) { - return_highestLanePriority = NoLanePriority; - return NoLanes; - } - - var nextLanes = NoLanes; - var nextLanePriority = NoLanePriority; - var expiredLanes = root.expiredLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; // Check if any work has expired. - if (expiredLanes !== NoLanes) { - nextLanes = expiredLanes; - nextLanePriority = return_highestLanePriority = SyncLanePriority; - } else { - // Do not work on any idle work until all the non-idle work has finished, - // even if the work is suspended. - var nonIdlePendingLanes = pendingLanes & NonIdleLanes; + return ""; +} - if (nonIdlePendingLanes !== NoLanes) { - var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; +var hasOwnProperty = Object.prototype.hasOwnProperty; - if (nonIdleUnblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; +var loggedTypeFailures = {}; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - if (nonIdlePingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); - nextLanePriority = return_highestLanePriority; - } - } +function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV( + element.type, + element._source, + owner ? owner.type : null + ); + ReactDebugCurrentFrame.setExtraStackFrame(stack); } else { - // The only remaining work is Idle. - var unblockedLanes = pendingLanes & ~suspendedLanes; - - if (unblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(unblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - if (pingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(pingedLanes); - nextLanePriority = return_highestLanePriority; - } - } + ReactDebugCurrentFrame.setExtraStackFrame(null); } } +} - if (nextLanes === NoLanes) { - // This should only be reachable if we're suspended - // TODO: Consider warning in this path if a fallback timer is not scheduled. - return NoLanes; - } // If there are higher priority lanes, we'll include them even if they - // are suspended. - - nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt - // it and we'll lose our progress. We should only do this if the new lanes are - // higher priority. +function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(hasOwnProperty); - if ( - wipLanes !== NoLanes && - wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't - // bother waiting until the root is complete. - (wipLanes & suspendedLanes) === NoLanes - ) { - getHighestPriorityLanes(wipLanes); - var wipLanePriority = return_highestLanePriority; + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. - if (nextLanePriority <= wipLanePriority) { - return wipLanes; - } else { - return_highestLanePriority = nextLanePriority; - } - } // Check for entangled lanes and add them to the batch. - // - // A lane is said to be entangled with another when it's not allowed to render - // in a batch that does not also include the other lane. Typically we do this - // when multiple updates have the same source, and we only want to respond to - // the most recent event from that source. - // - // Note that we apply entanglements *after* checking for partial work above. - // This means that if a lane is entangled during an interleaved event while - // it's already rendering, we won't interrupt it. This is intentional, since - // entanglement is usually "best effort": we'll try our best to render the - // lanes in the same batch, but it's not worth throwing out partially - // completed work in order to do it. - // - // For those exceptions where entanglement is semantically important, like - // useMutableSource, we should ensure that there is no partial work at the - // time we apply the entanglement. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error( + (componentName || "React class") + + ": " + + location + + " type `" + + typeSpecName + + "` is invalid; " + + "it must be a function, usually from the `prop-types` package, but received `" + + typeof typeSpecs[typeSpecName] + + "`." + + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." + ); + err.name = "Invariant Violation"; + throw err; + } - var entangledLanes = root.entangledLanes; + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - if (entangledLanes !== NoLanes) { - var entanglements = root.entanglements; - var lanes = nextLanes & entangledLanes; + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - nextLanes |= entanglements[index]; - lanes &= ~lane; - } - } + error( + "%s: type specification of %s" + + " `%s` is invalid; the type checker " + + "function must return `null` or an `Error` but returned a %s. " + + "You may have forgotten to pass an argument to the type checker " + + "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + + "shape all require an argument).", + componentName || "React class", + location, + typeSpecName, + typeof error$1 + ); - return nextLanes; -} -function getMostRecentEventTime(root, lanes) { - var eventTimes = root.eventTimes; - var mostRecentEventTime = NoTimestamp; + setCurrentlyValidatingElement(null); + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var eventTime = eventTimes[index]; + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); - if (eventTime > mostRecentEventTime) { - mostRecentEventTime = eventTime; - } + error("Failed %s type: %s", location, error$1.message); - lanes &= ~lane; + setCurrentlyValidatingElement(null); + } + } + } } - - return mostRecentEventTime; } -function computeExpirationTime(lane, currentTime) { - // TODO: Expiration heuristic is constant per lane, so could use a map. - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; +var valueStack = []; +var fiberStack; - if (priority >= InputContinuousLanePriority) { - // User interactions should expire slightly more quickly. - // - // NOTE: This is set to the corresponding constant as in Scheduler.js. When - // we made it larger, a product metric in www regressed, suggesting there's - // a user interaction that's being starved by a series of synchronous - // updates. If that theory is correct, the proper solution is to fix the - // starvation. However, this scenario supports the idea that expiration - // times are an important safeguard when starvation does happen. - // - // Also note that, in the case of user input specifically, this will soon no - // longer be an issue because we plan to make user input synchronous by - // default (until you enter `startTransition`, of course.) - // - // If weren't planning to make these updates synchronous soon anyway, I - // would probably make this number a configurable parameter. - return currentTime + 250; - } else if (priority >= TransitionPriority) { - return currentTime + 5000; - } else { - // Anything idle priority or lower should never expire. - return NoTimestamp; - } +{ + fiberStack = []; } -function markStarvedLanesAsExpired(root, currentTime) { - // TODO: This gets called every time we yield. We can optimize by storing - // the earliest expiration time on the root. Then use that to quickly bail out - // of this function. - var pendingLanes = root.pendingLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; - var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their - // expiration time. If so, we'll assume the update is being starved and mark - // it as expired to force it to finish. - - var lanes = pendingLanes; +var index = -1; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var expirationTime = expirationTimes[index]; +function createCursor(defaultValue) { + return { + current: defaultValue + }; +} - if (expirationTime === NoTimestamp) { - // Found a pending lane with no expiration time. If it's not suspended, or - // if it's pinged, assume it's CPU-bound. Compute a new expiration time - // using the current time. - if ( - (lane & suspendedLanes) === NoLanes || - (lane & pingedLanes) !== NoLanes - ) { - // Assumes timestamps are monotonically increasing. - expirationTimes[index] = computeExpirationTime(lane, currentTime); - } - } else if (expirationTime <= currentTime) { - // This lane expired - root.expiredLanes |= lane; +function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); } - lanes &= ~lane; + return; } -} // This returns the highest priority pending lanes regardless of whether they -function getLanesToRetrySynchronouslyOnError(root) { - var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - if (everythingButOffscreen !== NoLanes) { - return everythingButOffscreen; + { + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } } - if (everythingButOffscreen & OffscreenLane) { - return OffscreenLane; + cursor.current = valueStack[index]; + valueStack[index] = null; + + { + fiberStack[index] = null; } - return NoLanes; -} -function returnNextLanesPriority() { - return return_highestLanePriority; -} -function includesNonIdleWork(lanes) { - return (lanes & NonIdleLanes) !== NoLanes; -} -function includesOnlyRetries(lanes) { - return (lanes & RetryLanes) === lanes; + index--; } -function includesOnlyTransitions(lanes) { - return (lanes & TransitionLanes) === lanes; -} // To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. - -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case NoLanePriority: - break; - - case SyncLanePriority: - return SyncLane; - case SyncBatchedLanePriority: - return SyncBatchedLane; +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; - case InputDiscreteLanePriority: { - var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); + { + fiberStack[index] = fiber; + } - if (_lane === NoLane) { - // Shift to the next priority level - return findUpdateLane(InputContinuousLanePriority, wipLanes); - } + cursor.current = value; +} - return _lane; - } +var warnedAboutMissingGetChildContext; - case InputContinuousLanePriority: { - var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); +{ + warnedAboutMissingGetChildContext = {}; +} - if (_lane2 === NoLane) { - // Shift to the next priority level - return findUpdateLane(DefaultLanePriority, wipLanes); - } +var emptyContextObject = {}; - return _lane2; - } +{ + Object.freeze(emptyContextObject); +} // A cursor to the current merged context object on the stack. - case DefaultLanePriority: { - var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); +var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. - if (_lane3 === NoLane) { - // If all the default lanes are already being worked on, look for a - // lane in the transition range. - _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); +var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. +// We use this to get access to the parent context after we have already +// pushed the next context provider, and now need to merge their contexts. - if (_lane3 === NoLane) { - // All the transition lanes are taken, too. This should be very - // rare, but as a last resort, pick a default lane. This will have - // the effect of interrupting the current work-in-progress render. - _lane3 = pickArbitraryLane(DefaultLanes); - } - } +var previousContext = emptyContextObject; - return _lane3; +function getUnmaskedContext( + workInProgress, + Component, + didPushOwnContextIfProvider +) { + { + if (didPushOwnContextIfProvider && isContextProvider(Component)) { + // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; } - case TransitionPriority: // Should be handled by findTransitionLane instead - - case RetryLanePriority: - // Should be handled by findRetryLane instead - break; - - case IdleLanePriority: - var lane = pickArbitraryLane(IdleLanes & ~wipLanes); - - if (lane === NoLane) { - lane = pickArbitraryLane(IdleLanes); - } - - return lane; + return contextStackCursor.current; } +} +function cacheContext(workInProgress, unmaskedContext, maskedContext) { { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. - -function findTransitionLane(wipLanes, pendingLanes) { - // First look for lanes that are completely unclaimed, i.e. have no - // pending work. - var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); - - if (lane === NoLane) { - // If all lanes have pending work, look for a lane that isn't currently - // being worked on. - lane = pickArbitraryLane(TransitionLanes & ~wipLanes); - - if (lane === NoLane) { - // If everything is being worked on, pick any lane. This has the - // effect of interrupting the current work-in-progress. - lane = pickArbitraryLane(TransitionLanes); - } + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; } +} - return lane; -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. - -function findRetryLane(wipLanes) { - // This is a fork of `findUpdateLane` designed specifically for Suspense - // "retries" — a special update that attempts to flip a Suspense boundary - // from its placeholder state to its primary/resolved state. - var lane = pickArbitraryLane(RetryLanes & ~wipLanes); +function getMaskedContext(workInProgress, unmaskedContext) { + { + var type = workInProgress.type; + var contextTypes = type.contextTypes; - if (lane === NoLane) { - lane = pickArbitraryLane(RetryLanes); - } + if (!contextTypes) { + return emptyContextObject; + } // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. - return lane; -} + var instance = workInProgress.stateNode; -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} + if ( + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + ) { + return instance.__reactInternalMemoizedMaskedChildContext; + } -function getLowestPriorityLane(lanes) { - // This finds the most significant non-zero bit. - var index = 31 - clz32(lanes); - return index < 0 ? NoLanes : 1 << index; -} + var context = {}; -function getEqualOrHigherPriorityLanes(lanes) { - return (getLowestPriorityLane(lanes) << 1) - 1; -} + for (var key in contextTypes) { + context[key] = unmaskedContext[key]; + } -function pickArbitraryLane(lanes) { - // This wrapper function gets inlined. Only exists so to communicate that it - // doesn't matter which bit is selected; you can pick any bit without - // affecting the algorithms where its used. Here I'm using - // getHighestPriorityLane because it requires the fewest operations. - return getHighestPriorityLane(lanes); -} + { + var name = getComponentNameFromFiber(workInProgress) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + // Context is created before the class component is instantiated so check for instance. -function pickArbitraryLaneIndex(lanes) { - return 31 - clz32(lanes); -} + if (instance) { + cacheContext(workInProgress, unmaskedContext, context); + } -function laneToIndex(lane) { - return pickArbitraryLaneIndex(lane); + return context; + } } -function includesSomeLane(a, b) { - return (a & b) !== NoLanes; -} -function isSubsetOfLanes(set, subset) { - return (set & subset) === subset; -} -function mergeLanes(a, b) { - return a | b; +function hasContextChanged() { + { + return didPerformWorkStackCursor.current; + } } -function removeLanes(set, subset) { - return set & ~subset; -} // Seems redundant, but it changes the type from a single lane (used for -// updates) to a group of lanes (used for flushing work). -function laneToLanes(lane) { - return lane; +function isContextProvider(type) { + { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; + } } -function createLaneMap(initial) { - // Intentionally pushing one by one. - // https://v8.dev/blog/elements-kinds#avoid-creating-holes - var laneMap = []; - for (var i = 0; i < TotalLanes; i++) { - laneMap.push(initial); +function popContext(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } - - return laneMap; } -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But - // it's not practical to try every single possible combination. We need a - // heuristic to decide which lanes to attempt to render, and in which batches. - // For now, we use the same heuristic as in the old ExpirationTimes model: - // retry any lane at equal or lower priority, but don't try updates at higher - // priority without also including the lower priority updates. This works well - // when considering updates across different priority levels, but isn't - // sufficient for updates within the same priority, since we want to treat - // those updates as parallel. - // Unsuspend any update at equal or lower priority. - - var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 - - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - var eventTimes = root.eventTimes; - var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most - // recent event, and we assume time is monotonically increasing. - eventTimes[index] = eventTime; +function popTopLevelContextObject(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } } -function markRootSuspended(root, suspendedLanes) { - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. - var expirationTimes = root.expirationTimes; - var lanes = suspendedLanes; +function pushTopLevelContextObject(fiber, context, didChange) { + { + if (!(contextStackCursor.current === emptyContextObject)) { + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } } -function markRootPinged(root, pingedLanes, eventTime) { - root.pingedLanes |= root.suspendedLanes & pingedLanes; -} -function hasDiscreteLanes(lanes) { - return (lanes & InputDiscreteLanes) !== NoLanes; -} -function markRootMutableRead(root, updateLane) { - root.mutableReadLanes |= updateLane & root.pendingLanes; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; // Let's try everything again - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - var entanglements = root.entanglements; - var eventTimes = root.eventTimes; - var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work +function processChildContext(fiber, type, parentContext) { + { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. - var lanes = noLongerPendingLanes; + if (typeof instance.getChildContext !== "function") { + { + var componentName = getComponentNameFromFiber(fiber) || "Unknown"; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] = NoLanes; - eventTimes[index] = NoTimestamp; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } -} -function markRootEntangled(root, entangledLanes) { - root.entangledLanes |= entangledLanes; - var entanglements = root.entanglements; - var lanes = entangledLanes; + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] |= entangledLanes; - lanes &= ~lane; - } -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. -// Based on: -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 + error( + "%s.childContextTypes is specified but there is no getChildContext() method " + + "on the instance. You can either define getChildContext() on %s or remove " + + "childContextTypes from it.", + componentName, + componentName + ); + } + } -var log = Math.log; -var LN2 = Math.LN2; + return parentContext; + } -function clz32Fallback(lanes) { - if (lanes === 0) { - return 32; - } + var childContext = instance.getChildContext(); - return (31 - ((log(lanes) / LN2) | 0)) | 0; -} + for (var contextKey in childContext) { + if (!(contextKey in childContextTypes)) { + throw Error( + (getComponentNameFromFiber(fiber) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); + } + } -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; + { + var name = getComponentNameFromFiber(fiber) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); + } -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); + return Object.assign({}, parentContext, childContext); } } -var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. +function pushContextProvider(workInProgress) { + { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. -var ImmediatePriority$1 = 99; -var UserBlockingPriority$1 = 98; -var NormalPriority$1 = 97; -var LowPriority$1 = 96; -var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. + var memoizedMergedChildContext = + (instance && instance.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. -var NoPriority$1 = 90; -var shouldYield = Scheduler_shouldYield; -var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. - Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; -var syncQueue = null; -var immediateQueueCallbackNode = null; -var isFlushingSyncQueue = false; -var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// This will be the case for modern browsers that support `performance.now`. In -// older browsers, Scheduler falls back to `Date.now`, which returns a Unix -// timestamp. In that case, subtract the module initialization time to simulate -// the behavior of performance.now and keep our times small enough to fit -// within 32 bits. -// TODO: Consider lifting this into Scheduler. - -var now = - initialTimeMs$1 < 10000 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return ImmediatePriority$1; + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); + return true; + } +} - case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; +function invalidateContextProvider(workInProgress, type, didChange) { + { + var instance = workInProgress.stateNode; - case Scheduler_NormalPriority: - return NormalPriority$1; + if (!instance) { + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); + } - case Scheduler_LowPriority: - return LowPriority$1; + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext( + workInProgress, + type, + previousContext + ); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. - case Scheduler_IdlePriority: - return IdlePriority$1; + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. - default: { - throw Error("Unknown priority level."); + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } } } -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case ImmediatePriority$1: - return Scheduler_ImmediatePriority; +function findCurrentUnmaskedContext(fiber) { + { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ); + } + + var node = fiber; + + do { + switch (node.tag) { + case HostRoot: + return node.stateNode.context; - case UserBlockingPriority$1: - return Scheduler_UserBlockingPriority; + case ClassComponent: { + var Component = node.type; - case NormalPriority$1: - return Scheduler_NormalPriority; + if (isContextProvider(Component)) { + return node.stateNode.__reactInternalMemoizedMergedChildContext; + } - case LowPriority$1: - return Scheduler_LowPriority; + break; + } + } - case IdlePriority$1: - return Scheduler_IdlePriority; + node = node.return; + } while (node !== null); - default: { - throw Error("Unknown priority level."); + { + throw Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ); } } } -function runWithPriority(reactPriorityLevel, fn) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(priorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(priorityLevel, callback, options); -} +var LegacyRoot = 0; +var ConcurrentRoot = 1; + +var syncQueue = null; +var includesLegacySyncCallbacks = false; +var isFlushingSyncQueue = false; 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 - ); + syncQueue = [callback]; } 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 scheduleLegacySyncCallback(callback) { + includesLegacySyncCallbacks = true; + scheduleSyncCallback(callback); } -function flushSyncCallbackQueue() { - if (immediateQueueCallbackNode !== null) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); +function flushSyncCallbacksOnlyInLegacyMode() { + // Only flushes the queue if there's a legacy sync callback scheduled. + // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So + // it might make more sense for the queue to be a list of roots instead of a + // list of generic callbacks. Then we can have two: one for legacy roots, one + // for concurrent roots. And this method would only flush the legacy ones. + if (includesLegacySyncCallbacks) { + flushSyncCallbacks(); } - - flushSyncCallbackQueueImpl(); } - -function flushSyncCallbackQueueImpl() { +function flushSyncCallbacks() { if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. isFlushingSyncQueue = true; var i = 0; + var previousUpdatePriority = getCurrentUpdatePriority(); + + try { + var isSync = true; + var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this + // queue is in the render or commit phases. - { - try { - var _isSync2 = true; - var _queue = syncQueue; - runWithPriority(ImmediatePriority$1, function() { - for (; i < _queue.length; i++) { - var callback = _queue[i]; - - do { - callback = callback(_isSync2); - } while (callback !== null); - } - }); - syncQueue = null; - } catch (error) { - // If something throws, leave the remaining callbacks on the queue. - if (syncQueue !== null) { - syncQueue = syncQueue.slice(i + 1); - } // Resume flushing in the next tick - - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ); - throw error; - } finally { - isFlushingSyncQueue = false; + setCurrentUpdatePriority(DiscreteEventPriority); + + for (; i < queue.length; i++) { + var callback = queue[i]; + + do { + callback = callback(isSync); + } while (callback !== null); } + + syncQueue = null; + includesLegacySyncCallbacks = false; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); + } // Resume flushing in the next tick + + scheduleCallback(ImmediatePriority, flushSyncCallbacks); + throw error; + } finally { + setCurrentUpdatePriority(previousUpdatePriority); + isFlushingSyncQueue = false; } } + + return null; } -// TODO: this is special because it gets imported during build. -var ReactVersion = "17.0.1-454c2211c"; +var NoFlags$1 = + /* */ + 0; // Represents whether effect should fire. + +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. -var NoMode = 0; -var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root -// tag instead +var Layout = + /* */ + 2; +var Passive$1 = + /* */ + 4; -var BlockingMode = 2; -var ConcurrentMode = 4; -var ProfileMode = 8; -var DebugTracingMode = 16; +var ReactVersion = "17.0.3-2d8d133e1"; var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = 0; @@ -5635,7 +5717,6 @@ function is(x, y) { var objectIs = typeof Object.is === "function" ? Object.is : is; -var hasOwnProperty = Object.prototype.hasOwnProperty; /** * Performs equality by iterating through keys on an object and returning false * when any key has values which are not strictly equal between the arguments. @@ -5736,7 +5817,7 @@ function getCurrentFiberOwnerNameInDevOrNull() { var owner = current._debugOwner; if (owner !== null && typeof owner !== "undefined") { - return getComponentName(owner.type); + return getComponentNameFromFiber(owner); } } @@ -5793,7 +5874,7 @@ var ReactStrictModeWarnings = { var node = fiber; while (node !== null) { - if (node.mode & StrictMode) { + if (node.mode & StrictLegacyMode) { maybeStrictRoot = node; } @@ -5824,7 +5905,7 @@ var ReactStrictModeWarnings = { fiber, instance ) { - // Dedup strategy: Warn once per component. + // Dedupe strategy: Warn once per component. if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } @@ -5837,7 +5918,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function" ) { pendingUNSAFE_ComponentWillMountWarnings.push(fiber); @@ -5851,7 +5932,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); @@ -5865,7 +5946,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function" ) { pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); @@ -5879,7 +5960,7 @@ var ReactStrictModeWarnings = { if (pendingComponentWillMountWarnings.length > 0) { pendingComponentWillMountWarnings.forEach(function(fiber) { componentWillMountUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -5891,7 +5972,7 @@ var ReactStrictModeWarnings = { if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { UNSAFE_componentWillMountUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -5903,7 +5984,7 @@ var ReactStrictModeWarnings = { if (pendingComponentWillReceivePropsWarnings.length > 0) { pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { componentWillReceivePropsUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -5915,7 +5996,7 @@ var ReactStrictModeWarnings = { if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { UNSAFE_componentWillReceivePropsUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -5927,7 +6008,7 @@ var ReactStrictModeWarnings = { if (pendingComponentWillUpdateWarnings.length > 0) { pendingComponentWillUpdateWarnings.forEach(function(fiber) { componentWillUpdateUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -5939,7 +6020,7 @@ var ReactStrictModeWarnings = { if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { UNSAFE_componentWillUpdateUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -6094,7 +6175,7 @@ var ReactStrictModeWarnings = { var firstFiber = fiberArray[0]; var uniqueNames = new Set(); fiberArray.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); + uniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); didWarnAboutLegacyContext.add(fiber.type); }); var sortedNames = setToSortedString(uniqueNames); @@ -6145,11 +6226,6 @@ function resolveDefaultProps(Component, baseProps) { return baseProps; } -// Max 31 bit integer. The max integer size in V8 for 32-bit systems. -// Math.pow(2, 30) - 1 -// 0b111111111111111111111111111111 -var MAX_SIGNED_31_BIT_INT = 1073741823; - var valueCursor = createCursor(null); var rendererSigil; @@ -6160,14 +6236,14 @@ var rendererSigil; var currentlyRenderingFiber = null; var lastContextDependency = null; -var lastContextWithAllBitsObserved = null; +var lastFullyObservedContext = 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; + lastFullyObservedContext = null; { isDisallowedContextReadInDEV = false; @@ -6183,9 +6259,7 @@ function exitDisallowedContextReadInDEV() { isDisallowedContextReadInDEV = false; } } -function pushProvider(providerFiber, nextValue) { - var context = providerFiber.type._context; - +function pushProvider(providerFiber, context, nextValue) { { push(valueCursor, context._currentValue2, providerFiber); context._currentValue2 = nextValue; @@ -6206,38 +6280,14 @@ function pushProvider(providerFiber, nextValue) { } } } -function popProvider(providerFiber) { +function popProvider(context, providerFiber) { var currentValue = valueCursor.current; pop(valueCursor, providerFiber); - var context = providerFiber.type._context; { context._currentValue2 = currentValue; } } -function calculateChangedBits(context, newValue, oldValue) { - if (objectIs(oldValue, newValue)) { - // No change - return 0; - } else { - var changedBits = - typeof context._calculateChangedBits === "function" - ? context._calculateChangedBits(oldValue, newValue) - : MAX_SIGNED_31_BIT_INT; - - { - if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { - error( - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); - } - } - - return changedBits | 0; - } -} function scheduleWorkOnParentPath(parent, renderLanes) { // Update the child lanes of all the ancestors, including the alternates. var node = parent; @@ -6265,12 +6315,13 @@ function scheduleWorkOnParentPath(parent, renderLanes) { node = node.return; } } -function propagateContextChange( - workInProgress, - context, - changedBits, - renderLanes -) { +function propagateContextChange(workInProgress, context, renderLanes) { + { + propagateContextChange_eager(workInProgress, context, renderLanes); + } +} + +function propagateContextChange_eager(workInProgress, context, renderLanes) { var fiber = workInProgress.child; if (fiber !== null) { @@ -6289,23 +6340,35 @@ function propagateContextChange( while (dependency !== null) { // Check if the context matches. - if ( - dependency.context === context && - (dependency.observedBits & changedBits) !== 0 - ) { + if (dependency.context === context) { // Match! Schedule an update on this fiber. if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate( - NoTimestamp, - pickArbitraryLane(renderLanes) - ); + var lane = pickArbitraryLane(renderLanes); + var update = createUpdate(NoTimestamp, lane); update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the // update to the current fiber, too, which means it will persist even if // this render is thrown away. Since it's a race condition, not sure it's // worth fixing. + // Inlined `enqueueUpdate` to remove interleaved update check + + var updateQueue = fiber.updateQueue; + + if (updateQueue === null); + else { + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - enqueueUpdate(fiber, update); + sharedQueue.pending = update; + } } fiber.lanes = mergeLanes(fiber.lanes, renderLanes); @@ -6366,23 +6429,25 @@ function propagateContextChange( function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; lastContextDependency = null; - lastContextWithAllBitsObserved = null; + lastFullyObservedContext = null; var dependencies = workInProgress.dependencies; if (dependencies !== null) { - var firstContext = dependencies.firstContext; + { + var firstContext = dependencies.firstContext; - if (firstContext !== null) { - if (includesSomeLane(dependencies.lanes, renderLanes)) { - // Context list has a pending update. Mark that this fiber performed work. - markWorkInProgressReceivedUpdate(); - } // Reset the work-in-progress list + if (firstContext !== null) { + if (includesSomeLane(dependencies.lanes, renderLanes)) { + // Context list has a pending update. Mark that this fiber performed work. + markWorkInProgressReceivedUpdate(); + } // Reset the work-in-progress list - dependencies.firstContext = null; + dependencies.firstContext = null; + } } } } -function readContext(context, observedBits) { +function readContext(context) { { // This warning would fire if you read context inside a Hook like useMemo. // Unlike the class check below, it's not enforced in production for perf. @@ -6396,25 +6461,13 @@ function readContext(context, observedBits) { } } - if (lastContextWithAllBitsObserved === context); - else if (observedBits === false || observedBits === 0); - else { - var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. - - if ( - typeof observedBits !== "number" || - observedBits === MAX_SIGNED_31_BIT_INT - ) { - // Observe all updates. - lastContextWithAllBitsObserved = context; - resolvedObservedBits = MAX_SIGNED_31_BIT_INT; - } else { - resolvedObservedBits = observedBits; - } + var value = context._currentValue2; + if (lastFullyObservedContext === context); + else { var contextItem = { context: context, - observedBits: resolvedObservedBits, + memoizedValue: value, next: null }; @@ -6429,6 +6482,7 @@ function readContext(context, observedBits) { currentlyRenderingFiber.dependencies = { lanes: NoLanes, firstContext: contextItem, + // TODO: This is an old field. Delete it. responders: null }; } else { @@ -6437,7 +6491,49 @@ function readContext(context, observedBits) { } } - return context._currentValue2; + return value; +} + +// An array of all update queues that received updates during the current +// render. When this render exits, either because it finishes or because it is +// interrupted, the interleaved updates will be transfered onto the main part +// of the queue. +var interleavedQueues = null; +function pushInterleavedQueue(queue) { + if (interleavedQueues === null) { + interleavedQueues = [queue]; + } else { + interleavedQueues.push(queue); + } +} +function enqueueInterleavedUpdates() { + // Transfer the interleaved updates onto the main queue. Each queue has a + // `pending` field and an `interleaved` field. When they are not null, they + // point to the last node in a circular linked list. We need to append the + // interleaved list to the end of the pending list by joining them into a + // single, circular list. + if (interleavedQueues !== null) { + for (var i = 0; i < interleavedQueues.length; i++) { + var queue = interleavedQueues[i]; + var lastInterleavedUpdate = queue.interleaved; + + if (lastInterleavedUpdate !== null) { + queue.interleaved = null; + var firstInterleavedUpdate = lastInterleavedUpdate.next; + var lastPendingUpdate = queue.pending; + + if (lastPendingUpdate !== null) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = firstInterleavedUpdate; + lastInterleavedUpdate.next = firstPendingUpdate; + } + + queue.pending = lastInterleavedUpdate; + } + } + + interleavedQueues = null; + } } var UpdateState = 0; @@ -6462,7 +6558,9 @@ function initializeUpdateQueue(fiber) { firstBaseUpdate: null, lastBaseUpdate: null, shared: { - pending: null + pending: null, + interleaved: null, + lanes: NoLanes }, effects: null }; @@ -6495,7 +6593,7 @@ function createUpdate(eventTime, lane) { }; return update; } -function enqueueUpdate(fiber, update) { +function enqueueUpdate(fiber, update, lane) { var updateQueue = fiber.updateQueue; if (updateQueue === null) { @@ -6504,17 +6602,35 @@ function enqueueUpdate(fiber, update) { } var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (isInterleavedUpdate(fiber)) { + var interleaved = sharedQueue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(sharedQueue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + sharedQueue.interleaved = update; } else { - update.next = pending.next; - pending.next = update; - } + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - sharedQueue.pending = update; + sharedQueue.pending = update; + } { if ( @@ -6532,6 +6648,33 @@ function enqueueUpdate(fiber, update) { } } } +function entangleTransitions(root, fiber, lane) { + var updateQueue = fiber.updateQueue; + + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; + } + + var sharedQueue = updateQueue.shared; + + if (isTransitionLane(lane)) { + var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must + // have finished. We can remove them from the shared queue, which represents + // a superset of the actually pending lanes. In some cases we may entangle + // more than we need to, but that's OK. In fact it's worse if we *don't* + // entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } +} function enqueueCapturedUpdate(workInProgress, capturedUpdate) { // Captured updates are updates that are thrown by a child during the render // phase. They should be discarded if the render is aborted. Therefore, @@ -6801,7 +6944,11 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { ); var callback = update.callback; - if (callback !== null) { + if ( + callback !== null && // If the update was already committed, we should not queue its + // callback again. + update.lane !== NoLane + ) { workInProgress.flags |= Callback; var effects = queue.effects; @@ -6841,7 +6988,24 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { queue.baseState = newBaseState; queue.firstBaseUpdate = newFirstBaseUpdate; - queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. + queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.shared.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + newLanes = mergeLanes(newLanes, interleaved.lane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (firstBaseUpdate === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.shared.lanes = NoLanes; + } // Set the remaining expiration time to be whatever is remaining in the queue. // This should be fine because the only two other things that contribute to // expiration time are props and context. We're already in the middle of the // begin phase by the time we start processing the queue, so we've already @@ -6894,8 +7058,7 @@ function commitUpdateQueue(finishedWork, finishedQueue, instance) { } } -var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -6942,7 +7105,7 @@ var didWarnAboutInvalidateContextType; warnOnUndefinedDerivedState = function(type, partialState) { if (partialState === undefined) { - var componentName = getComponentName(type) || "Component"; + var componentName = getComponentNameFromType(type) || "Component"; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); @@ -7000,6 +7163,7 @@ function applyDerivedStateFromProps( updateQueue.baseState = memoizedState; } } + var classComponentUpdater = { isMounted: isMounted, enqueueSetState: function(inst, payload, callback) { @@ -7018,7 +7182,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); @@ -7037,7 +7205,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); @@ -7055,7 +7227,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } } }; @@ -7082,7 +7258,7 @@ function checkShouldComponentUpdate( error( "%s.shouldComponentUpdate(): Returned undefined instead of a " + "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" + getComponentNameFromType(ctor) || "Component" ); } } @@ -7103,7 +7279,7 @@ function checkClassInstance(workInProgress, ctor, newProps) { var instance = workInProgress.stateNode; { - var name = getComponentName(ctor) || "Component"; + var name = getComponentNameFromType(ctor) || "Component"; var renderPresent = instance.render; if (!renderPresent) { @@ -7206,7 +7382,7 @@ function checkClassInstance(workInProgress, ctor, newProps) { "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", - getComponentName(ctor) || "A pure component" + getComponentNameFromType(ctor) || "A pure component" ); } @@ -7276,7 +7452,7 @@ function checkClassInstance(workInProgress, ctor, newProps) { error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", - getComponentName(ctor) + getComponentNameFromType(ctor) ); } @@ -7375,7 +7551,7 @@ function constructClassInstance(workInProgress, ctor, props) { error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", - getComponentName(ctor) || "Component", + getComponentNameFromType(ctor) || "Component", addendum ); } @@ -7403,7 +7579,7 @@ function constructClassInstance(workInProgress, ctor, props) { { if (typeof ctor.getDerivedStateFromProps === "function" && state === null) { - var componentName = getComponentName(ctor) || "Component"; + var componentName = getComponentNameFromType(ctor) || "Component"; if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); @@ -7464,7 +7640,7 @@ function constructClassInstance(workInProgress, ctor, props) { foundWillReceivePropsName !== null || foundWillUpdateName !== null ) { - var _componentName = getComponentName(ctor) || "Component"; + var _componentName = getComponentNameFromType(ctor) || "Component"; var newApiName = typeof ctor.getDerivedStateFromProps === "function" @@ -7517,7 +7693,7 @@ function callComponentWillMount(workInProgress, instance) { "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", - getComponentName(workInProgress.type) || "Component" + getComponentNameFromFiber(workInProgress) || "Component" ); } @@ -7543,7 +7719,8 @@ function callComponentWillReceiveProps( if (instance.state !== oldState) { { - var componentName = getComponentName(workInProgress.type) || "Component"; + var componentName = + getComponentNameFromFiber(workInProgress) || "Component"; if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); @@ -7582,7 +7759,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { { if (instance.state === newProps) { - var componentName = getComponentName(ctor) || "Component"; + var componentName = getComponentNameFromType(ctor) || "Component"; if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); @@ -7596,7 +7773,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -7611,7 +7788,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; @@ -7640,7 +7816,9 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + var fiberFlags = Update; + + workInProgress.flags |= fiberFlags; } } @@ -7702,7 +7880,9 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + var fiberFlags = Update; + + workInProgress.flags |= fiberFlags; } return false; @@ -7748,13 +7928,17 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + var _fiberFlags = Update; + + workInProgress.flags |= _fiberFlags; } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + var _fiberFlags2 = Update; + + workInProgress.flags |= _fiberFlags2; } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -7833,7 +8017,8 @@ function updateClassInstance( unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && - !checkHasForceUpdateAfterProcessing() + !checkHasForceUpdateAfterProcessing() && + !enableLazyContextPropagation ) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. @@ -7878,7 +8063,11 @@ function updateClassInstance( oldState, newState, nextContext - ); + ) || // TODO: In some cases, we'll end up checking if context has changed twice, + // both before and after `shouldComponentUpdate` has been called. Not ideal, + // but I'm loath to refactor this function. This only happens for memoized + // components so it's not that common. + enableLazyContextPropagation; if (shouldUpdate) { // In order to support react-lifecycles-compat polyfilled components, @@ -7974,7 +8163,7 @@ var warnForMissingKey = function(child, returnFiber) {}; } child._store.validated = true; - var componentName = getComponentName(returnFiber.type) || "Component"; + var componentName = getComponentNameFromFiber(returnFiber) || "Component"; if (ownerHasKeyUseWarning[componentName]) { return; @@ -7990,8 +8179,6 @@ var warnForMissingKey = function(child, returnFiber) {}; }; } -var isArray$1 = Array.isArray; - function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; @@ -8004,7 +8191,7 @@ function coerceRef(returnFiber, current, element) { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant if ( - (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + (returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs // because these cannot be automatically converted to an arrow function // using a codemod. Therefore, we don't have to warn about string refs again. !( @@ -8013,7 +8200,8 @@ function coerceRef(returnFiber, current, element) { element._owner.stateNode !== element._self ) ) { - var componentName = getComponentName(returnFiber.type) || "Component"; + var componentName = + getComponentNameFromFiber(returnFiber) || "Component"; if (!didWarnAboutStringRefs[componentName]) { { @@ -8105,22 +8293,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { - if (returnFiber.type !== "textarea") { - { - throw 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) + - "). If you meant to render a collection of children, use an array instead." - ); - } + var childString = Object.prototype.toString.call(newChild); + + { + throw Error( + "Objects are not valid as a React child (found: " + + (childString === "[object Object]" + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : childString) + + "). If you meant to render a collection of children, use an array instead." + ); } } function warnOnFunctionType(returnFiber) { { - var componentName = getComponentName(returnFiber.type) || "Component"; + var componentName = getComponentNameFromFiber(returnFiber) || "Component"; if (ownerHasFunctionTypeWarning[componentName]) { return; @@ -8134,7 +8322,7 @@ function warnOnFunctionType(returnFiber) { "Or maybe you meant to call this function rather than return it." ); } -} // This wrapper function exists because I expect to clone the code in each path +} // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. @@ -8144,23 +8332,16 @@ function ChildReconciler(shouldTrackSideEffects) { if (!shouldTrackSideEffects) { // Noop. return; - } // Deletions are added in reversed order so we add it to the front. - // At this point, the return fiber's effect list is empty except for - // deletions, so we can just append the deletion to the list. The remaining - // effects aren't added until the complete phase. Once we implement - // resuming, this may not be true. + } - var last = returnFiber.lastEffect; + var deletions = returnFiber.deletions; - if (last !== null) { - last.nextEffect = childToDelete; - returnFiber.lastEffect = childToDelete; + if (deletions === null) { + returnFiber.deletions = [childToDelete]; + returnFiber.flags |= ChildDeletion; } else { - returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + deletions.push(childToDelete); } - - childToDelete.nextEffect = null; - childToDelete.flags = Deletion; } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -8224,7 +8405,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (oldIndex < lastPlacedIndex) { // This is a move. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } else { // This item can stay in place. @@ -8232,7 +8413,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } else { // This is an insertion. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } } @@ -8241,7 +8422,7 @@ function ChildReconciler(shouldTrackSideEffects) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { - newFiber.flags = Placement; + newFiber.flags |= Placement; } return newFiber; @@ -8262,10 +8443,26 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current, element, lanes) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + } + if (current !== null) { if ( - current.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current, element) + current.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + enableLazyElements ) { // Move based on index var existing = useFiber(current, element.props); @@ -8361,7 +8558,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, @@ -8404,16 +8601,6 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ); - } - return updateElement(returnFiber, oldFiber, newChild, lanes); } else { return null; @@ -8429,7 +8616,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -8471,16 +8658,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key === null ? newIdx : newChild.key ) || null; - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - _matchedFiber, - newChild.props.children, - lanes, - newChild.key - ); - } - return updateElement(returnFiber, _matchedFiber, newChild, lanes); } @@ -8494,7 +8671,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateFragment( @@ -8974,45 +9151,43 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - switch (child.tag) { - case Fragment: { - if (element.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, element.props.children); - existing.return = returnFiber; + var elementType = element.type; - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; - return existing; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - break; + return existing; } + } else { + if ( + child.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + enableLazyElements + ) { + deleteRemainingChildren(returnFiber, child.sibling); - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing = useFiber(child, element.props); - - _existing.ref = coerceRef(returnFiber, child, element); - _existing.return = returnFiber; + var _existing = useFiber(child, element.props); - { - _existing._debugSource = element._source; - _existing._debugOwner = element._owner; - } + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; - return _existing; + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; } - break; + return _existing; } } // Didn't match. @@ -9106,9 +9281,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild = newChild.props.children; } // Handle object types - var isObject = typeof newChild === "object" && newChild !== null; - - if (isObject) { + if (typeof newChild === "object" && newChild !== null) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return placeSingleChild( @@ -9130,6 +9303,26 @@ function ChildReconciler(shouldTrackSideEffects) { ) ); } + + if (isArray(newChild)) { + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + } + + if (getIteratorFn(newChild)) { + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); } if (typeof newChild === "string" || typeof newChild === "number") { @@ -9143,28 +9336,6 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray$1(newChild)) { - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - } - - if (getIteratorFn(newChild)) { - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - } - - if (isObject) { - throwOnInvalidObjectType(returnFiber, newChild); - } - { if (typeof newChild === "function") { warnOnFunctionType(returnFiber); @@ -9195,7 +9366,7 @@ function ChildReconciler(shouldTrackSideEffects) { case SimpleMemoComponent: { { throw Error( - (getComponentName(returnFiber.type) || "Component") + + (getComponentNameFromFiber(returnFiber) || "Component") + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." ); } @@ -9443,21 +9614,6 @@ function findFirstSuspended(row) { return null; } -var NoFlags$1 = - /* */ - 0; // Represents whether effect should fire. - -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ - 2; -var Passive$1 = - /* */ - 4; - var isHydrating = false; function enterHydrationState(fiber) { @@ -9553,6 +9709,12 @@ function warnAboutMultipleRenderersDEV(mutableSource) { } } // Eager reads the version of a mutable source and stores it on the root. +function getSuspendedCachePool() { + { + return null; + } // We check the cache on the stack first, since that's the one any new Caches +} + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; @@ -9625,7 +9787,7 @@ function updateHookTypesDev() { function checkDepsAreArrayDev(deps) { { - if (deps !== undefined && deps !== null && !Array.isArray(deps)) { + if (deps !== undefined && deps !== null && !isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. error( @@ -9640,7 +9802,7 @@ function checkDepsAreArrayDev(deps) { function warnOnHookMismatchInDev(currentHookName) { { - var componentName = getComponentName(currentlyRenderingFiber$1.type); + var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1); if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { didWarnAboutMismatchedHooksForComponent.add(componentName); @@ -9838,7 +10000,25 @@ function renderWithHooks( { currentHookNameInDev = null; hookTypesDev = null; - hookTypesUpdateIndexDev = -1; + hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last + // render. If this fires, it suggests that we incorrectly reset the static + // flags in some other part of the codebase. This has happened before, for + // example, in the SuspenseList implementation. + + if ( + current !== null && + (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird + // and creates false positives. To make this work in legacy mode, we'd + // need to mark fibers that commit in an incomplete state, somehow. For + // now I'll disable the warning that most of the bugs that would trigger + // it are either exclusive to concurrent mode or exist in both. + (current.mode & ConcurrentMode) !== NoMode + ) { + error( + "Internal React error: Expected static flag was missing. Please " + + "notify the React team." + ); + } } didScheduleRenderPhaseUpdate = false; @@ -9852,8 +10032,13 @@ function renderWithHooks( return children; } function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; - workInProgress.flags &= ~(Passive | Update); + workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the + // complete phase (bubbleProperties). + + { + workInProgress.flags &= ~(Passive | Update); + } + current.lanes = removeLanes(current.lanes, lanes); } function resetHooksAfterThrow() { @@ -10004,6 +10189,8 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState @@ -10141,6 +10328,28 @@ function updateReducer(reducer, initialArg, init) { hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; + } // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + var interleavedLane = interleaved.lane; + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + interleavedLane + ); + markSkippedUpdateLanes(interleavedLane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (baseQueue === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.lanes = NoLanes; } var dispatch = queue.dispatch; @@ -10268,11 +10477,50 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { // // This can lead to tearing in the first renderer when it resumes, // but there's nothing we can do about that (short of throwing here and refusing to continue the render). - markSourceAsDirty(source); + markSourceAsDirty(source); // Intentioally throw an error to force React to retry synchronously. During + // the synchronous retry, it will block interleaved mutations, so we should + // get a consistent read. Therefore, the following error should never be + // visible to the user. + // + // If it were to become visible to the user, it suggests one of two things: + // a bug in React, or (more likely), a mutation during the render phase that + // caused the second re-render attempt to be different from the first. + // + // We know it's the second case if the logs are currently disabled. So in + // dev, we can present a more accurate error message. + + { + // eslint-disable-next-line react-internal/no-production-logging + if (console.log.__reactDisabledLog) { + // If the logs are disabled, this is the dev-only double render. This is + // only reachable if there was a mutation during render. Show a helpful + // error message. + // + // Something interesting to note: because we only double render in + // development, this error will never happen during production. This is + // actually true of all errors that occur during a double render, + // because if the first render had thrown, we would have exited the + // begin phase without double rendering. We should consider suppressing + // any error from a double render (with a warning) to more closely match + // the production behavior. + var componentName = getComponentNameFromFiber( + currentlyRenderingFiber$1 + ); + + { + throw Error( + "A mutable source was mutated while the " + + componentName + + " component was rendering. This is not supported. Move any mutations into event handlers or effects." + ); + } + } + } // We expect this error not to be thrown during the synchronous retry, + // because we blocked interleaved mutations. { throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } } @@ -10408,6 +10656,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { // including any interleaving updates that occur. var newQueue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -10455,6 +10705,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -10548,7 +10800,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); return; } } @@ -10564,15 +10816,19 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { } function mountEffect(create, deps) { - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + { + return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); + } } function updateEffect(create, deps) { - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + return updateEffectImpl(Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + var fiberFlags = Update; + + return mountEffectImpl(fiberFlags, Layout, create, deps); } function updateLayoutEffect(create, deps) { @@ -10624,8 +10880,10 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; + var fiberFlags = Update; + return mountEffectImpl( - Update, + fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps @@ -10780,31 +11038,20 @@ function rerenderDeferredValue(value) { } function startTransition(setPending, callback) { - var priorityLevel = getCurrentPriorityLevel(); - - { - runWithPriority( - priorityLevel < UserBlockingPriority$1 - ? UserBlockingPriority$1 - : priorityLevel, - function() { - setPending(true); - } - ); - runWithPriority( - priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = 1; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - } - ); + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority( + higherEventPriority(previousPriority, ContinuousEventPriority) + ); + setPending(true); + var prevTransition = ReactCurrentBatchConfig$1.transition; + ReactCurrentBatchConfig$1.transition = 1; + + try { + setPending(false); + callback(); + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$1.transition = prevTransition; } } @@ -10816,7 +11063,7 @@ function mountTransition() { var start = startTransition.bind(null, setPending); var hook = mountWorkInProgressHook(); hook.memoizedState = start; - return [start, isPending]; + return [isPending, start]; } function updateTransition() { @@ -10825,7 +11072,7 @@ function updateTransition() { var hook = updateWorkInProgressHook(); var start = hook.memoizedState; - return [start, isPending]; + return [isPending, start]; } function rerenderTransition() { @@ -10834,7 +11081,7 @@ function rerenderTransition() { var hook = updateWorkInProgressHook(); var start = hook.memoizedState; - return [start, isPending]; + return [isPending, start]; } var isUpdatingOpaqueValueInRenderPhase = false; @@ -10847,7 +11094,7 @@ function getIsUpdatingOpaqueValueInRenderPhaseInDEV() { function warnOnOpaqueIdentifierAccessInDEV(fiber) { { // TODO: Should warn in effects and callbacks, too - var name = getComponentName(fiber.type) || "Unknown"; + var name = getComponentNameFromFiber(fiber) || "Unknown"; if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) { error( @@ -10904,19 +11151,7 @@ function dispatchAction(fiber, queue, action) { eagerReducer: null, eagerState: null, next: null - }; // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - queue.pending = update; + }; var alternate = fiber.alternate; if ( @@ -10927,7 +11162,47 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; } else { + if (isInterleavedUpdate(fiber)) { + var interleaved = queue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + queue.interleaved = update; + } else { + var _pending = queue.pending; + + if (_pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = _pending.next; + _pending.next = update; + } + + queue.pending = update; + } + if ( fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes) @@ -10972,7 +11247,24 @@ function dispatchAction(fiber, queue, action) { } } - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (isTransitionLane(lane) && root !== null) { + var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they + // must have finished. We can remove them from the shared queue, which + // represents a superset of the actually pending lanes. In some cases we + // may entangle more than we need to, but that's OK. In fact it's worse if + // we *don't* entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } } } @@ -10994,6 +11286,7 @@ var ContextOnlyDispatcher = { useOpaqueIdentifier: throwInvalidHookError, unstable_isNewReconciler: enableNewReconciler }; + var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; @@ -11022,8 +11315,8 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }; HooksDispatcherOnMountInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); + readContext: function(context) { + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; @@ -11031,10 +11324,10 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; checkDepsAreArrayDev(deps); return mountCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; mountHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11123,19 +11416,20 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnMountWithHookTypesInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); + readContext: function(context) { + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; updateHookTypesDev(); return mountCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11220,19 +11514,20 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnUpdateInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); + readContext: function(context) { + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; updateHookTypesDev(); return updateCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11317,19 +11612,20 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnRerenderInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); + readContext: function(context) { + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; updateHookTypesDev(); return updateCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11414,10 +11710,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnMountInDEV = { - readContext: function(context, observedBits) { + readContext: function(context) { warnInvalidContextAccess(); - return readContext(context, observedBits); + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; @@ -11425,11 +11722,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; mountHookTypesDev(); return mountCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; warnInvalidHookAccess(); mountHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11526,10 +11823,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnUpdateInDEV = { - readContext: function(context, observedBits) { + readContext: function(context) { warnInvalidContextAccess(); - return readContext(context, observedBits); + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; @@ -11537,11 +11835,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; updateHookTypesDev(); return updateCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; warnInvalidHookAccess(); updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11638,10 +11936,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { - readContext: function(context, observedBits) { + readContext: function(context) { warnInvalidContextAccess(); - return readContext(context, observedBits); + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; @@ -11649,11 +11948,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; updateHookTypesDev(); return updateCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; warnInvalidHookAccess(); updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11903,7 +12202,7 @@ function updateForwardRef( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentNameFromType(Component) ); } } @@ -11991,7 +12290,7 @@ function updateMemoComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(type) + getComponentNameFromType(type) ); } } @@ -12021,7 +12320,7 @@ function updateMemoComponent( _innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(_type) + getComponentNameFromType(_type) ); } } @@ -12087,7 +12386,7 @@ function updateSimpleMemoComponent( outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps) "prop", - getComponentName(outerMemoType) + getComponentNameFromType(outerMemoType) ); } } @@ -12144,21 +12443,28 @@ function updateSimpleMemoComponent( function updateOffscreenComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; - var prevState = current !== null ? current.memoizedState : null; + var prevState = current !== null ? current.memoizedState : null; // If this is not null, this is a cache pool that was carried over from the + // previous render. We will push this to the cache pool context so that we can + // resume in-flight requests. + + var spawnedCachePool = null; if ( nextProps.mode === "hidden" || nextProps.mode === "unstable-defer-without-hiding" ) { + // Rendering a hidden tree. if ((workInProgress.mode & ConcurrentMode) === NoMode) { // In legacy sync mode, don't defer the subtree. Render it now. - // TODO: Figure out what we should do in Blocking mode. var nextState = { - baseLanes: NoLanes + baseLanes: NoLanes, + cachePool: null }; workInProgress.memoizedState = nextState; pushRenderLanes(workInProgress, renderLanes); } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. var nextBaseLanes; if (prevState !== null) { @@ -12168,25 +12474,24 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { nextBaseLanes = renderLanes; } // Schedule this fiber to re-render at offscreen priority. Then bailout. - { - markSpawnedWork(OffscreenLane); - } - workInProgress.lanes = workInProgress.childLanes = laneToLanes( OffscreenLane ); var _nextState = { - baseLanes: nextBaseLanes + baseLanes: nextBaseLanes, + cachePool: spawnedCachePool }; - workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway + workInProgress.memoizedState = _nextState; + workInProgress.updateQueue = null; // We're about to bail out, but we need to push this to the stack anyway // to avoid a push/pop misalignment. pushRenderLanes(workInProgress, nextBaseLanes); + return null; } else { - // Rendering at offscreen, so we can clear the base lanes. var _nextState2 = { - baseLanes: NoLanes + baseLanes: NoLanes, + cachePool: null }; workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. @@ -12195,10 +12500,12 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { pushRenderLanes(workInProgress, subtreeRenderLanes); } } else { + // Rendering a visible tree. var _subtreeRenderLanes; if (prevState !== null) { - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); workInProgress.memoizedState = null; } else { @@ -12233,12 +12540,7 @@ function updateMode(current, workInProgress, renderLanes) { function updateProfiler(current, workInProgress, renderLanes) { { - workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, - - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + workInProgress.flags |= Update; } var nextProps = workInProgress.pendingProps; @@ -12277,7 +12579,7 @@ function updateFunctionComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentNameFromType(Component) ); } } @@ -12336,7 +12638,7 @@ function updateClassComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentNameFromType(Component) ); } } @@ -12407,7 +12709,7 @@ function updateClassComponent( error( "It looks like %s is reassigning its own `this.props` while rendering. " + "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" + getComponentNameFromFiber(workInProgress) || "a component" ); } @@ -12523,10 +12825,11 @@ function updateHostRoot(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; + var prevChildren = prevState.element; cloneUpdateQueue(current, workInProgress); processUpdateQueue(workInProgress, nextProps, null, renderLanes); - var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property + var nextState = workInProgress.memoizedState; + var root = workInProgress.stateNode; // being called "element". var nextChildren = nextState.element; @@ -12535,8 +12838,6 @@ function updateHostRoot(current, workInProgress, renderLanes) { return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - var root = workInProgress.stateNode; - if (root.hydrate && enterHydrationState()) { var child = mountChildFibers( workInProgress, @@ -12683,7 +12984,7 @@ function mountLazyComponent( outerPropTypes, resolvedProps, // Resolved for outer only "prop", - getComponentName(Component) + getComponentNameFromType(Component) ); } } @@ -12803,7 +13104,7 @@ function mountIndeterminateComponent( Component.prototype && typeof Component.prototype.render === "function" ) { - var componentName = getComponentName(Component) || "Unknown"; + var componentName = getComponentNameFromType(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { error( @@ -12817,7 +13118,7 @@ function mountIndeterminateComponent( } } - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); } @@ -12845,7 +13146,7 @@ function mountIndeterminateComponent( typeof value.render === "function" && value.$$typeof === undefined ) { - var _componentName = getComponentName(Component) || "Unknown"; + var _componentName = getComponentNameFromType(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { error( @@ -12873,7 +13174,7 @@ function mountIndeterminateComponent( value.$$typeof === undefined ) { { - var _componentName2 = getComponentName(Component) || "Unknown"; + var _componentName2 = getComponentNameFromType(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName2]) { error( @@ -12910,17 +13211,6 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); - } - adoptClassInstance(workInProgress, value); mountClassInstance(workInProgress, Component, props, renderLanes); return finishClassComponent( @@ -12984,7 +13274,7 @@ function validateFunctionComponentInDev(workInProgress, Component) { } if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentName(Component) || "Unknown"; + var _componentName3 = getComponentNameFromType(Component) || "Unknown"; if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { error( @@ -13000,7 +13290,7 @@ function validateFunctionComponentInDev(workInProgress, Component) { typeof Component.contextType === "object" && Component.contextType !== null ) { - var _componentName4 = getComponentName(Component) || "Unknown"; + var _componentName4 = getComponentNameFromType(Component) || "Unknown"; if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { error( @@ -13021,13 +13311,17 @@ var SUSPENDED_MARKER = { function mountSuspenseOffscreenState(renderLanes) { return { - baseLanes: renderLanes + baseLanes: renderLanes, + cachePool: getSuspendedCachePool() }; } function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; + return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool }; } // TODO: Probably should inline this back @@ -13169,11 +13463,6 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { // it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } - return _fallbackFragment; } else { return mountSuspensePrimaryChildren( @@ -13310,7 +13599,10 @@ function mountSuspenseFallbackChildren( var primaryChildFragment; var fallbackChildFragment; - if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) { + if ( + (mode & ConcurrentMode) === NoMode && + progressedPrimaryFragment !== null + ) { // In legacy mode, we commit the primary tree as if it successfully // completed, even though it's in an inconsistent state. primaryChildFragment = progressedPrimaryFragment; @@ -13378,7 +13670,7 @@ function updateSuspensePrimaryChildren( } ); - if ((workInProgress.mode & BlockingMode) === NoMode) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { primaryChildFragment.lanes = renderLanes; } @@ -13387,9 +13679,14 @@ function updateSuspensePrimaryChildren( if (currentFallbackChildFragment !== null) { // Delete the fallback child fragment - currentFallbackChildFragment.nextEffect = null; - currentFallbackChildFragment.flags = Deletion; - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; + var deletions = workInProgress.deletions; + + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); + } } workInProgress.child = primaryChildFragment; @@ -13415,7 +13712,7 @@ function updateSuspenseFallbackChildren( if ( // In legacy mode, we commit the primary tree as if it successfully // completed, even though it's in an inconsistent state. - (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was + (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was // already cloned. In legacy mode, the only case where this isn't true is // when DevTools forces us to display a fallback; we skip the first render // pass entirely and go straight to rendering the fallback. (In Concurrent @@ -13439,28 +13736,21 @@ function updateSuspenseFallbackChildren( currentPrimaryChildFragment.selfBaseDuration; primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration; - } // The fallback fiber was added as a deletion effect during the first pass. + } // The fallback fiber was added as a deletion during the first pass. // However, since we're going to remain on the fallback, we no longer want - // to delete it. So we need to remove it from the list. Deletions are stored - // on the same list as effects. We want to keep the effects from the primary - // tree. So we copy the primary child fragment's effect list, which does not - // include the fallback deletion effect. - - var progressedLastEffect = primaryChildFragment.lastEffect; + // to delete it. - if (progressedLastEffect !== null) { - workInProgress.firstEffect = primaryChildFragment.firstEffect; - workInProgress.lastEffect = progressedLastEffect; - progressedLastEffect.nextEffect = null; - } else { - // TODO: Reset this somewhere else? Lol legacy mode is so weird. - workInProgress.firstEffect = workInProgress.lastEffect = null; - } + workInProgress.deletions = null; } else { primaryChildFragment = createWorkInProgressOffscreenFiber( currentPrimaryChildFragment, primaryChildProps - ); + ); // Since we're reusing a current tree, we need to reuse the flags, too. + // (We don't do this in legacy mode, because in legacy mode we don't re-use + // the current tree; see previous branch.) + + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; } var fallbackChildFragment; @@ -13656,11 +13946,12 @@ function validateTailOptions(tailMode, revealOrder) { function validateSuspenseListNestedChild(childSlot, index) { { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + var isAnArray = isArray(childSlot); + var isIterable = + !isAnArray && typeof getIteratorFn(childSlot) === "function"; - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; error( "A nested %s was passed to row #%s in . Wrap it in " + @@ -13688,7 +13979,7 @@ function validateSuspenseListChildren(children, revealOrder) { children !== null && children !== false ) { - if (Array.isArray(children)) { + if (isArray(children)) { for (var i = 0; i < children.length; i++) { if (!validateSuspenseListNestedChild(children[i], i)) { return; @@ -13730,8 +14021,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; @@ -13742,8 +14032,7 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }; } else { // We can reuse the existing object from previous renders. @@ -13753,7 +14042,6 @@ function initSuspenseListRenderState( renderState.last = lastContentRow; renderState.tail = tail; renderState.tailMode = tailMode; - renderState.lastEffect = lastEffectBeforeRendering; } } // This can end up rendering this component multiple passes. // The first pass splits the children fibers into two sets. A head and tail. @@ -13804,7 +14092,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { pushSuspenseContext(workInProgress, suspenseContext); - if ((workInProgress.mode & BlockingMode) === NoMode) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { // In legacy mode, SuspenseList doesn't work so we just // use make it a noop by treating it as the default revealOrder. workInProgress.memoizedState = null; @@ -13831,8 +14119,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { false, // isBackwards tail, lastContentRow, - tailMode, - workInProgress.lastEffect + tailMode ); break; } @@ -13866,8 +14153,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { true, // isBackwards _tail, null, // last - tailMode, - workInProgress.lastEffect + tailMode ); break; } @@ -13878,8 +14164,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { false, // isBackwards null, // tail null, // last - undefined, - workInProgress.lastEffect + undefined ); break; } @@ -13945,25 +14230,26 @@ function updateContextProvider(current, workInProgress, renderLanes) { } } - pushProvider(workInProgress, newValue); + pushProvider(workInProgress, context, newValue); - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); - - if (changedBits === 0) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + { + if (oldProps !== null) { + var oldValue = oldProps.value; + + if (objectIs(oldValue, newValue)) { + // No change. Bailout early if children are the same. + if (oldProps.children === newProps.children && !hasContextChanged()) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + } else { + // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange(workInProgress, context, renderLanes); } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange(workInProgress, context, changedBits, renderLanes); } } @@ -14018,7 +14304,7 @@ function updateContextConsumer(current, workInProgress, renderLanes) { } prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context, newProps.unstable_observedBits); + var newValue = readContext(context); var newChildren; { @@ -14054,13 +14340,14 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { // The children don't have any work either. We can skip them. // TODO: Once we add back resuming, we should check if the children are // a work-in-progress set. If so, we need to transfer their effects. - return null; - } else { - // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - cloneChildFibers(current, workInProgress); - return workInProgress.child; - } + { + return null; + } + } // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. + + cloneChildFibers(current, workInProgress); + return workInProgress.child; } function remountFiber(current, oldWorkInProgress, newWorkInProgress) { @@ -14101,17 +14388,15 @@ function remountFiber(current, oldWorkInProgress, newWorkInProgress) { } // Delete the old fiber and place the new one. // Since the old fiber is disconnected, we have to schedule it manually. - var last = returnFiber.lastEffect; + var deletions = returnFiber.deletions; - if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; + deletions.push(current); } - current.nextEffect = null; - current.flags = Deletion; newWorkInProgress.flags |= Placement; // Restart work from the new fiber. return newWorkInProgress; @@ -14184,7 +14469,8 @@ function beginWork(current, workInProgress, renderLanes) { case ContextProvider: { var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); + var context = workInProgress.type._context; + pushProvider(workInProgress, context, newValue); break; } @@ -14198,12 +14484,7 @@ function beginWork(current, workInProgress, renderLanes) { if (hasChildWork) { workInProgress.flags |= Update; - } // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, - - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + } } break; @@ -14247,6 +14528,9 @@ function beginWork(current, workInProgress, renderLanes) { // primary children and work on the fallback. return child.sibling; } else { + // Note: We can return `null` here because we already checked + // whether there were nested context consumers, via the call to + // `bailoutOnAlreadyFinishedWork` above. return null; } } @@ -14468,7 +14752,7 @@ function beginWork(current, workInProgress, renderLanes) { outerPropTypes, _resolvedProps3, // Resolved for outer only "prop", - getComponentName(_type2) + getComponentNameFromType(_type2) ); } } @@ -14518,10 +14802,6 @@ function beginWork(current, workInProgress, renderLanes) { return updateSuspenseListComponent(current, workInProgress, renderLanes); } - case FundamentalComponent: { - break; - } - case ScopeComponent: { break; } @@ -14554,6 +14834,34 @@ function markRef$1(workInProgress) { workInProgress.flags |= Ref; } +function hadNoMutationsEffects(current, completedWork) { + var didBailout = current !== null && current.child === completedWork.child; + + if (didBailout) { + return true; + } + + if ((completedWork.flags & ChildDeletion) !== NoFlags) { + return false; + } // TODO: If we move the `hadNoMutationsEffects` call after `bubbleProperties` + // then we only have to check the `completedWork.subtreeFlags`. + + var child = completedWork.child; + + while (child !== null) { + if ( + (child.flags & MutationMask) !== NoFlags || + (child.subtreeFlags & MutationMask) !== NoFlags + ) { + return false; + } + + child = child.sibling; + } + + return true; +} + var appendAllChildren; var updateHostContainer; var updateHostComponent$1; @@ -14680,15 +14988,15 @@ var updateHostText$1; appendChildToContainerChildSet(containerChildSet, instance); } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + var _instance2 = node.stateNode; if (needsVisibilityToggle && isHidden) { // This child is inside a timed out tree. Hide it. var text = node.memoizedProps; - _instance3 = cloneHiddenTextInstance(); + _instance2 = cloneHiddenTextInstance(); } - appendChildToContainerChildSet(containerChildSet, _instance3); + appendChildToContainerChildSet(containerChildSet, _instance2); } else if (node.tag === HostPortal); else if (node.tag === SuspenseComponent) { if ((node.flags & Update) !== NoFlags) { @@ -14751,9 +15059,9 @@ var updateHostText$1; } }; - updateHostContainer = function(workInProgress) { + updateHostContainer = function(current, workInProgress) { var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = workInProgress.firstEffect === null; + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); if (childrenUnchanged); else { @@ -14779,7 +15087,7 @@ var updateHostText$1; var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates. // This guarantees that we can reuse all of them. - var childrenUnchanged = workInProgress.firstEffect === null; + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); if (childrenUnchanged && oldProps === newProps) { // No changes, just reuse the existing instance. @@ -14921,6 +15229,115 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { } } +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; + + if (!didBailout) { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var actualDuration = completedWork.actualDuration; + var treeBaseDuration = completedWork.selfBaseDuration; + var child = completedWork.child; + + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes) + ); + subtreeFlags |= child.subtreeFlags; + subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will + // only be updated if work is done on the fiber (i.e. it doesn't bailout). + // When work is done, it should bubble to the parent's actualDuration. If + // the fiber has not been cloned though, (meaning no work was done), then + // this value will reflect the amount of time spent working on a previous + // render. In that case it should not bubble. We determine whether it was + // cloned by comparing the child pointer. + + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } + + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; + + while (_child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child.lanes, _child.childLanes) + ); + subtreeFlags |= _child.subtreeFlags; + subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child.return = completedWork; + _child = _child.sibling; + } + } + + completedWork.subtreeFlags |= subtreeFlags; + } else { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var _treeBaseDuration = completedWork.selfBaseDuration; + var _child2 = completedWork.child; + + while (_child2 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child2.lanes, _child2.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; + + while (_child3 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child3.lanes, _child3.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } + + completedWork.subtreeFlags |= subtreeFlags; + } + + completedWork.childLanes = newChildLanes; + return didBailout; +} + function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; @@ -14935,6 +15352,7 @@ function completeWork(current, workInProgress, renderLanes) { case Profiler: case ContextConsumer: case MemoComponent: + bubbleProperties(workInProgress); return null; case ClassComponent: { @@ -14944,14 +15362,16 @@ function completeWork(current, workInProgress, renderLanes) { popContext(workInProgress); } + bubbleProperties(workInProgress); return null; } case HostRoot: { + var fiberRoot = workInProgress.stateNode; + popHostContainer(workInProgress); popTopLevelContextObject(workInProgress); resetWorkInProgressVersions(); - var fiberRoot = workInProgress.stateNode; if (fiberRoot.pendingContext) { fiberRoot.context = fiberRoot.pendingContext; @@ -14976,7 +15396,8 @@ function completeWork(current, workInProgress, renderLanes) { } } - updateHostContainer(workInProgress); + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); return null; } @@ -15005,6 +15426,7 @@ function completeWork(current, workInProgress, renderLanes) { ); } // This can happen when we abort work. + bubbleProperties(workInProgress); return null; } @@ -15041,6 +15463,7 @@ function completeWork(current, workInProgress, renderLanes) { } } + bubbleProperties(workInProgress); return null; } @@ -15081,6 +15504,7 @@ function completeWork(current, workInProgress, renderLanes) { } } + bubbleProperties(workInProgress); return null; } @@ -15094,7 +15518,7 @@ function completeWork(current, workInProgress, renderLanes) { if ((workInProgress.mode & ProfileMode) !== NoMode) { transferActualDuration(workInProgress); - } + } // Don't bubble properties in this case. return workInProgress; } @@ -15110,12 +15534,10 @@ function completeWork(current, workInProgress, renderLanes) { } if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in blocking mode we can suspend, - // otherwise we won't suspend. // TODO: This will still suspend a synchronous tree if anything // in the concurrent tree already suspended during this render. // This is a known bug. - if ((workInProgress.mode & BlockingMode) !== NoMode) { + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { // TODO: Move this back to throwException because this is too late // if this is a large tree which is common for initial loads. We // don't know if we should restart a render or not until we get @@ -15155,22 +15577,42 @@ function completeWork(current, workInProgress, renderLanes) { } } + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment2 = workInProgress.child; + + if (_primaryChildFragment2 !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment2.treeBaseDuration; + } + } + } + } + return null; } case HostPortal: popHostContainer(workInProgress); - updateHostContainer(workInProgress); + updateHostContainer(current, workInProgress); if (current === null) { preparePortalMount(workInProgress.stateNode.containerInfo); } + bubbleProperties(workInProgress); return null; case ContextProvider: // Pop provider fiber - popProvider(workInProgress); + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); return null; case IncompleteClassComponent: { @@ -15182,6 +15624,7 @@ function completeWork(current, workInProgress, renderLanes) { popContext(workInProgress); } + bubbleProperties(workInProgress); return null; } @@ -15192,6 +15635,7 @@ function completeWork(current, workInProgress, renderLanes) { if (renderState === null) { // We're running in the default, "independent" mode. // We don't do anything in this mode. + bubbleProperties(workInProgress); return null; } @@ -15243,14 +15687,10 @@ function completeWork(current, workInProgress, renderLanes) { workInProgress.flags |= Update; } // Rerender the whole list, but this time, we'll force fallbacks // to stay in place. - // Reset the effect list before doing the second pass since that's now invalid. - - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } - - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. + workInProgress.subtreeFlags = NoFlags; resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately // rerender the children. @@ -15260,7 +15700,8 @@ function completeWork(current, workInProgress, renderLanes) { suspenseStackCursor.current, ForceSuspenseFallback ) - ); + ); // Don't bubble properties in this case. + return workInProgress.child; } @@ -15284,10 +15725,6 @@ function completeWork(current, workInProgress, renderLanes) { // since we're leaving it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } } } else { cutOffTailIfNeeded(renderState, false); @@ -15317,16 +15754,8 @@ function completeWork(current, workInProgress, renderLanes) { !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating. ) { - // We need to delete the row we just rendered. - // Reset the effect list to what it was before we rendered this - // child. The nested children have already appended themselves. - var lastEffect = (workInProgress.lastEffect = - renderState.lastEffect); // Remove any effects that were appended after this point. - - if (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. - + // We're done. + bubbleProperties(workInProgress); return null; } } else if ( @@ -15352,10 +15781,6 @@ function completeWork(current, workInProgress, renderLanes) { // since we're leaving it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } } } @@ -15386,7 +15811,6 @@ function completeWork(current, workInProgress, renderLanes) { var next = renderState.tail; renderState.rendering = next; renderState.tail = next.sibling; - renderState.lastEffect = workInProgress.lastEffect; renderState.renderingStartTime = now(); next.sibling = null; // Restore the context. // TODO: We can probably just avoid popping it instead and only @@ -15404,17 +15828,15 @@ function completeWork(current, workInProgress, renderLanes) { } pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. return next; } + bubbleProperties(workInProgress); return null; } - case FundamentalComponent: { - break; - } - case ScopeComponent: { break; } @@ -15422,12 +15844,12 @@ function completeWork(current, workInProgress, renderLanes) { case OffscreenComponent: case LegacyHiddenComponent: { popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; if (current !== null) { - var _nextState = workInProgress.memoizedState; var _prevState = current.memoizedState; var prevIsHidden = _prevState !== null; - var nextIsHidden = _nextState !== null; if ( prevIsHidden !== nextIsHidden && @@ -15435,6 +15857,14 @@ function completeWork(current, workInProgress, renderLanes) { ) { workInProgress.flags |= Update; } + } // Don't bubble properties for hidden children. + + if ( + !nextIsHidden || + includesSomeLane(subtreeRenderLanes, OffscreenLane) || + (workInProgress.mode & ConcurrentMode) === NoMode + ) { + bubbleProperties(workInProgress); } return null; @@ -15526,12 +15956,17 @@ function unwindWork(workInProgress, renderLanes) { return null; case ContextProvider: - popProvider(workInProgress); + var context = workInProgress.type._context; + popProvider(context, workInProgress); return null; case OffscreenComponent: case LegacyHiddenComponent: popRenderLanes(workInProgress); + + return null; + + case CacheComponent: return null; default: @@ -15539,7 +15974,7 @@ function unwindWork(workInProgress, renderLanes) { } } -function unwindInterruptedWork(interruptedWork) { +function unwindInterruptedWork(interruptedWork, renderLanes) { switch (interruptedWork.tag) { case ClassComponent: { var childContextTypes = interruptedWork.type.childContextTypes; @@ -15576,12 +16011,14 @@ function unwindInterruptedWork(interruptedWork) { break; case ContextProvider: - popProvider(interruptedWork); + var context = interruptedWork.type._context; + popProvider(context, interruptedWork); break; case OffscreenComponent: case LegacyHiddenComponent: popRenderLanes(interruptedWork); + break; } } @@ -15655,21 +16092,22 @@ function logCapturedError(boundary, errorInfo) { // https://github.com/facebook/react/pull/13384 } - var componentName = source ? getComponentName(source.type) : null; + var componentName = source ? getComponentNameFromFiber(source) : null; var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : "The above error occurred in one of your React components:"; var errorBoundaryMessage; - var errorBoundaryName = getComponentName(boundary.type); - if (errorBoundaryName) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); - } else { + if (boundary.tag === HostRoot) { errorBoundaryMessage = "Consider adding an error boundary to your tree to customize error handling behavior.\n" + "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + } else { + var errorBoundaryName = + getComponentNameFromFiber(boundary) || "Anonymous"; + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); } var combinedMessage = @@ -15769,7 +16207,7 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { error( "%s: Error boundaries should implement getDerivedStateFromError(). " + "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" + getComponentNameFromFiber(fiber) || "Unknown" ); } } @@ -15808,6 +16246,7 @@ function attachPingListener(root, wakeable, lanes) { // Memoize using the thread ID to prevent redundant listeners. threadIDs.add(lanes); var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); } } @@ -15820,21 +16259,24 @@ function throwException( rootRenderLanes ) { // The source fiber did not complete. - sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. - - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= Incomplete; if ( value !== null && typeof value === "object" && typeof value.then === "function" ) { - // This is a wakeable. var wakeable = value; + // A legacy mode Suspense quirk, only relevant to hook components. + + var tag = sourceFiber.tag; - if ((sourceFiber.mode & BlockingMode) === NoMode) { - // Reset the memoizedState to what it was before we attempted - // to render it. + if ( + (sourceFiber.mode & ConcurrentMode) === NoMode && + (tag === FunctionComponent || + tag === ForwardRef || + tag === SimpleMemoComponent) + ) { var currentSource = sourceFiber.alternate; if (currentSource) { @@ -15870,16 +16312,24 @@ function throwException( _workInProgress.updateQueue = updateQueue; } else { wakeables.add(wakeable); - } // If the boundary is outside of blocking mode, we should *not* + } // If the boundary is in legacy mode, we should *not* // suspend the commit. Pretend as if the suspended component rendered // null and keep rendering. In the commit phase, we'll schedule a // subsequent synchronous update to re-render the Suspense. // // Note: It doesn't matter whether the component that suspended was - // inside a blocking mode tree. If the Suspense is outside of it, we + // inside a concurrent mode tree. If the Suspense is outside of it, we // should *not* suspend the commit. + // + // If the suspense boundary suspended itself suspended, we don't have to + // do this trick because nothing was partially started. We can just + // directly do a second pass over the fallback in this render and + // pretend we meant to render that directly. - if ((_workInProgress.mode & BlockingMode) === NoMode) { + if ( + (_workInProgress.mode & ConcurrentMode) === NoMode && + _workInProgress !== returnFiber + ) { _workInProgress.flags |= DidCapture; sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. // But we shouldn't call any lifecycle methods or callbacks. Remove @@ -15888,9 +16338,9 @@ function throwException( sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); if (sourceFiber.tag === ClassComponent) { - var currentSourceFiber = sourceFiber.alternate; + var _currentSourceFiber = sourceFiber.alternate; - if (currentSourceFiber === null) { + if (_currentSourceFiber === null) { // This is a new mount. Change the tag so it's not mistaken for a // completed class component. For example, we should not call // componentWillUnmount if it is deleted. @@ -15962,7 +16412,7 @@ function throwException( // TODO: Use invariant so the message is stripped in prod? value = new Error( - (getComponentName(sourceFiber.type) || "A React component") + + (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n" + "\n" + "Add a component higher in the tree to " + @@ -16030,9 +16480,9 @@ var didWarnAboutUndefinedSnapshotBeforeUpdate = null; { didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} - +} // Used during the commit phase to track the state of the Offscreen component stack. var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +var nextEffect = null; // Used for Profiling builds to track updaters. var callComponentWillUnmountWithTimer = function(current, instance) { instance.props = current.memoizedProps; @@ -16041,9 +16491,13 @@ var callComponentWillUnmountWithTimer = function(current, instance) { { instance.componentWillUnmount(); } -}; // Capture errors so they don't interrupt unmounting. +}; // Capture errors so they don't interrupt mounting. -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance +) { { invokeGuardedCallback( null, @@ -16055,12 +16509,12 @@ function safelyCallComponentWillUnmount(current, instance) { if (hasCaughtError()) { var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current, nearestMountedAncestor, unmountError); } } -} +} // Capture errors so they don't interrupt mounting. -function safelyDetachRef(current) { +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (ref !== null) { @@ -16072,7 +16526,7 @@ function safelyDetachRef(current) { if (hasCaughtError()) { var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } } } else { @@ -16081,27 +16535,117 @@ function safelyDetachRef(current) { } } -function safelyCallDestroy(current, destroy) { +function safelyCallDestroy(current, nearestMountedAncestor, destroy) { { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { var error = clearCaughtError(); - captureCommitPhaseError(current, error); + captureCommitPhaseError(current, nearestMountedAncestor, error); } } } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { +var focusedInstanceHandle = null; +var shouldFireAfterActiveInstanceBlur = false; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = prepareForCommit(root.containerInfo); + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber + + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + focusedInstanceHandle = null; + return shouldFire; +} + +function commitBeforeMutationEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization + + var deletions = fiber.deletions; + + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var deletion = deletions[i]; + commitBeforeMutationEffectsDeletion(deletion); + } + } + + var child = fiber.child; + + if ( + (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && + child !== null + ) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitBeforeMutationEffects_complete(); + } + } +} + +function commitBeforeMutationEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; + + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitBeforeMutationEffectsOnFiber, + null, + fiber + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); + } + + var sibling = fiber.sibling; + + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; return; } - case ClassComponent: { - if (finishedWork.flags & Snapshot) { + nextEffect = fiber.return; + } +} + +function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; + + if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { + // Check to see if the focused element was inside of a hidden (Suspense) subtree. + // TODO: Move this out of the hot path using a dedicated effect tag. + if ( + finishedWork.tag === SuspenseComponent && + isSuspenseBoundaryBeingHidden(current, finishedWork) && + doesFiberContain(finishedWork, focusedInstanceHandle) + ) { + shouldFireAfterActiveInstanceBlur = true; + } + } + + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(finishedWork); + + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + break; + } + + case ClassComponent: { if (current !== null) { var prevProps = current.memoizedProps; var prevState = current.memoizedState; @@ -16121,7 +16665,7 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { "This might either be because of a bug in React, or because " + "a component reassigns its own `this.props`. " + "Please file an issue.", - getComponentName(finishedWork.type) || "instance" + getComponentNameFromFiber(finishedWork) || "instance" ); } @@ -16132,7 +16676,7 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { "This might either be because of a bug in React, or because " + "a component reassigns its own `this.state`. " + "Please file an issue.", - getComponentName(finishedWork.type) || "instance" + getComponentNameFromFiber(finishedWork) || "instance" ); } } @@ -16154,38 +16698,56 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { error( "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) + getComponentNameFromFiber(finishedWork) ); } } instance.__reactInternalSnapshotBeforeUpdate = snapshot; } + + break; } - return; - } + case HostRoot: { + break; + } - case HostRoot: { - return; + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + break; + + default: { + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } } - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types - return; + resetCurrentFiber(); } +} - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); +function commitBeforeMutationEffectsDeletion(deletion) { + // TODO (effects) It would be nice to avoid calling doesFiberContain() + // Maybe we can repurpose one of the subtreeFlags positions for this instead? + // Use it to store which part of the tree the focused instance is in? + // This assumes we can safely determine that instance during the "render" phase. + if (doesFiberContain(deletion, focusedInstanceHandle)) { + shouldFireAfterActiveInstanceBlur = true; } } -function commitHookEffectListUnmount(tag, finishedWork) { +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor +) { var updateQueue = finishedWork.updateQueue; var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; @@ -16194,13 +16756,13 @@ function commitHookEffectListUnmount(tag, finishedWork) { var effect = firstEffect; do { - if ((effect.tag & tag) === tag) { + if ((effect.tag & flags) === flags) { // Unmount var destroy = effect.destroy; effect.destroy = undefined; if (destroy !== undefined) { - destroy(); + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); } } @@ -16260,626 +16822,1097 @@ function commitHookEffectListMount(tag, finishedWork) { } } - effect = effect.next; - } while (effect !== firstEffect); - } -} + effect = effect.next; + } while (effect !== firstEffect); + } +} + +function commitLayoutEffectOnFiber( + finishedRoot, + current, + finishedWork, + committedLanes +) { + if ((finishedWork.flags & (Update | Callback)) !== NoFlags) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } + + break; + } + + case ClassComponent: { + var instance = finishedWork.stateNode; + + if (finishedWork.flags & Update) { + if (current === null) { + // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + } + } + + { + instance.componentDidMount(); + } + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + } + } + + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + + var updateQueue = finishedWork.updateQueue; + + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + + commitUpdateQueue(finishedWork, updateQueue, instance); + } + + break; + } + + case HostRoot: { + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; + + if (_updateQueue !== null) { + var _instance = null; + + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; + + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + } + + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } + + break; + } + + case HostComponent: { + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. + + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(); + } + + break; + } + + case HostText: { + // We have no life-cycles associated with text. + break; + } + + case HostPortal: { + // We have no life-cycles associated with portals. + break; + } + + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); + var phase = current === null ? "mount" : "update"; + + if (typeof onRender === "function") { + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime + ); + } + } + + break; + } + + case SuspenseComponent: { + break; + } + + case SuspenseListComponent: + case IncompleteClassComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + break; + + default: { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + } + + { + if (finishedWork.flags & Ref) { + commitAttachRef(finishedWork); + } + } +} + +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; + + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; + + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; + + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag + + if (typeof ref === "function") { + { + ref(instanceToUse); + } + } else { + { + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentNameFromFiber(finishedWork) + ); + } + } + + ref.current = instanceToUse; + } + } +} + +function commitDetachRef(current) { + var currentRef = current.ref; + + if (currentRef !== null) { + if (typeof currentRef === "function") { + { + currentRef(null); + } + } else { + currentRef.current = null; + } + } +} // User-originating errors (lifecycles and refs) should not interrupt +// deletion, so don't let them throw. Host-originating errors should +// interrupt deletion, so it's okay + +function commitUnmount(finishedRoot, current, nearestMountedAncestor) { + onCommitUnmount(current); + + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + var updateQueue = current.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + + if (destroy !== undefined) { + if ((tag & Layout) !== NoFlags$1) { + { + safelyCallDestroy(current, nearestMountedAncestor, destroy); + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } + + return; + } + + case ClassComponent: { + safelyDetachRef(current, nearestMountedAncestor); + var instance = current.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance + ); + } + + return; + } -function schedulePassiveEffects(finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + case HostComponent: { + safelyDetachRef(current, nearestMountedAncestor); + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. + { + emptyPortalContainer(current); + } - do { - var _effect = effect, - next = _effect.next, - tag = _effect.tag; + return; + } - if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); - enqueuePendingPassiveHookEffectMount(finishedWork, effect); - } + case DehydratedFragment: { + return; + } - effect = next; - } while (effect !== firstEffect); + case ScopeComponent: { + return; + } } } -function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - // At this point layout effects have already been destroyed (during mutation phase). - // This is done to prevent sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. - { - commitHookEffectListMount(Layout | HasEffect, finishedWork); - } +function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor) { + // While we're inside a removed host node we don't want to call + // removeChild on the inner nodes because they're removed by the top + // call anyway. We also want to call componentWillUnmount on all + // composites before this host node is removed from the tree. Therefore + // we do an inner loop while we're still inside the host node. + var node = root; + + while (true) { + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. + // Skip portals because commitUnmount() currently visits them recursively. + + if ( + node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. + // If we don't use mutation we drill down into portals here instead. + !supportsMutation + ) { + node.child.return = node; + node = node.child; + continue; + } - schedulePassiveEffects(finishedWork); + if (node === root) { return; } - case ClassComponent: { - var instance = finishedWork.stateNode; + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; + } - if (finishedWork.flags & Update) { - if (current === null) { - // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + node = node.return; + } - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + node.sibling.return = node.return; + node = node.sibling; + } +} - { - instance.componentDidMount(); - } - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. +function detachFiberMutation(fiber) { + // Cut off the return pointer to disconnect it from the tree. + // This enables us to detect and warn against state updates on an unmounted component. + // It also prevents events from bubbling from within disconnected components. + // + // Ideally, we should also clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. + // This child itself will be GC:ed when the parent updates the next time. + // + // Note that we can't clear child or sibling pointers yet. + // They're needed for passive effects and for findDOMNode. + // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). + // + // Don't reset the alternate yet, either. We need that so we can detach the + // alternate's fields in the passive phase. Clearing the return pointer is + // sufficient for findDOMNode semantics. + var alternate = fiber.alternate; - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (alternate !== null) { + alternate.return = null; + } - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + fiber.return = null; +} - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - } - } // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. +function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; - var updateQueue = finishedWork.updateQueue; + if (alternate !== null) { + fiber.alternate = null; + detachFiberAfterEffects(alternate); + } // Note: Defensively using negation instead of < in case + // `deletedTreeCleanUpLevel` is undefined. - if (updateQueue !== null) { - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + { + // This is the default branch (level 0). + fiber.child = null; + fiber.deletions = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.sibling = null; + fiber.stateNode = null; + fiber.updateQueue = null; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + { + fiber._debugOwner = null; + } + } +} - commitUpdateQueue(finishedWork, updateQueue, instance); - } +function emptyPortalContainer(current) { + var portal = current.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); +} +function commitContainer(finishedWork) { + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: { return; } - case HostRoot: { - // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. - var _updateQueue = finishedWork.updateQueue; + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; + return; + } + } - if (_updateQueue !== null) { - var _instance = null; + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } +} - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; +function commitDeletion(finishedRoot, current, nearestMountedAncestor) { + { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current, nearestMountedAncestor); + } - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } + detachFiberMutation(current); +} + +function commitWork(current, finishedWork) { + { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); } - commitUpdateQueue(finishedWork, _updateQueue, _instance); + return; } - return; - } + case Profiler: { + return; + } - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } - if (current === null && finishedWork.flags & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - commitMount(); + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; } - return; - } + case HostRoot: { + break; + } - case HostText: { - // We have no life-cycles associated with text. - return; + case OffscreenComponent: + case LegacyHiddenComponent: { + return; + } } - case HostPortal: { - // We have no life-cycles associated with portals. - return; + commitContainer(finishedWork); + return; + } +} + +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; + + if (newState !== null) { + markCommitTimeOfFallback(); + } +} + +function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; + + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); } - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - current === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } - } + if (!retryCache.has(wakeable)) { + retryCache.add(wakeable); + + wakeable.then(retry, retry); } + }); + } +} // This function detects when a Suspense boundary goes from visible to hidden. +// It returns false if the boundary is already hidden. +// TODO: Use an effect tag. - return; - } +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + if (current !== null) { + var oldState = current.memoizedState; - case SuspenseComponent: { - return; + if (oldState === null || oldState.dehydrated !== null) { + var newState = finishedWork.memoizedState; + return newState !== null && newState.dehydrated === null; } - - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - case OffscreenComponent: - case LegacyHiddenComponent: - return; } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } + return false; } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +function commitMutationEffects(root, firstChild, committedLanes) { + nextEffect = firstChild; + commitMutationEffects_begin(root); +} - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; +function commitMutationEffects_begin(root) { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; + var deletions = fiber.deletions; - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; - if (typeof ref === "function") { - { - ref(instanceToUse); - } - } else { - { - if (!ref.hasOwnProperty("current")) { - error( - "Unexpected ref object provided for %s. " + - "Use either a ref-setter function or React.createRef().", - getComponentName(finishedWork.type) + { + invokeGuardedCallback( + null, + commitDeletion, + null, + root, + childToDelete, + fiber ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(childToDelete, fiber, error); + } } } + } - ref.current = instanceToUse; + var child = fiber.child; + + if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitMutationEffects_complete(root); } } } -function commitDetachRef(current) { - var currentRef = current.ref; +function commitMutationEffects_complete(root) { + while (nextEffect !== null) { + var fiber = nextEffect; - if (currentRef !== null) { - if (typeof currentRef === "function") { - { - currentRef(null); + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitMutationEffectsOnFiber, + null, + fiber, + root + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - } else { - currentRef.current = null; + + resetCurrentFiber(); } - } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay -function commitUnmount(finishedRoot, current, renderPriorityLevel) { - onCommitUnmount(current); + var sibling = fiber.sibling; - switch (current.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - var updateQueue = current.updateQueue; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; + nextEffect = fiber.return; + } +} - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; +function commitMutationEffectsOnFiber(finishedWork, root) { + var flags = finishedWork.flags; - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; + if (flags & Ref) { + var current = finishedWork.alternate; - if (destroy !== undefined) { - if ((tag & Passive$1) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(current, effect); - } else { - { - safelyCallDestroy(current, destroy); - } - } - } + if (current !== null) { + commitDetachRef(current); + } + } // The following switch statement is only concerned about placement, + // updates, and deletions. To avoid needing to add a case for every possible + // bitmap value, we remove the secondary effects from the effect tag and + // switch on that value. - effect = effect.next; - } while (effect !== firstEffect); - } - } + var primaryFlags = flags & (Placement | Update | Hydrating); - return; + switch (primaryFlags) { + case Placement: { + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + + finishedWork.flags &= ~Placement; + break; } - case ClassComponent: { - safelyDetachRef(current); - var instance = current.stateNode; + case PlacementAndUpdate: { + // inserted, before any life-cycles like componentDidMount gets called. - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, instance); - } + finishedWork.flags &= ~Placement; // Update - return; + var _current = finishedWork.alternate; + commitWork(_current, finishedWork); + break; } - case HostComponent: { - safelyDetachRef(current); - return; + case Hydrating: { + finishedWork.flags &= ~Hydrating; + break; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - emptyPortalContainer(current); - } + case HydratingAndUpdate: { + finishedWork.flags &= ~Hydrating; // Update - return; + var _current2 = finishedWork.alternate; + commitWork(_current2, finishedWork); + break; } - case FundamentalComponent: { - return; + case Update: { + var _current3 = finishedWork.alternate; + commitWork(_current3, finishedWork); + break; } + } +} - case DehydratedFragment: { - return; - } +function commitLayoutEffects(finishedWork, root, committedLanes) { + nextEffect = finishedWork; + commitLayoutEffects_begin(finishedWork, root, committedLanes); +} - case ScopeComponent: { - return; +function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; + + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; + + if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); } } } -function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; +function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; - while (true) { - commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. + while (nextEffect !== null) { + var fiber = nextEffect; - if ( - node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. - // If we don't use mutation we drill down into portals here instead. - !supportsMutation - ) { - node.child.return = node; - node = node.child; - continue; + if ((fiber.flags & LayoutMask) !== NoFlags) { + var current = fiber.alternate; + + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitLayoutEffectOnFiber, + null, + root, + current, + fiber, + committedLanes + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); + } } - if (node === root) { + if (fiber === subtreeRoot) { + nextEffect = null; return; } - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } + var sibling = fiber.sibling; - node = node.return; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - node.sibling.return = node.return; - node = node.sibling; + nextEffect = fiber.return; } } -function detachFiberMutation(fiber) { - // Cut off the return pointers to disconnect it from the tree. Ideally, we - // should clear the child pointer of the parent alternate to let this - // get GC:ed but we don't know which for sure which parent is the current - // one so we'll settle for GC:ing the subtree of this child. This child - // itself will be GC:ed when the parent updates the next time. - // Note: we cannot null out sibling here, otherwise it can cause issues - // with findDOMNode and how it requires the sibling field to carry out - // traversal in a later effect. See PR #16820. We now clear the sibling - // field after effects, see: detachFiberAfterEffects. - // - // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. - // It may be required if the current component is an error boundary, - // and one of its descendants throws while unmounting a passive effect. - fiber.alternate = null; - fiber.child = null; - fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.return = null; - fiber.updateQueue = null; +function commitPassiveMountEffects(root, finishedWork) { + nextEffect = finishedWork; + commitPassiveMountEffects_begin(finishedWork, root); +} - { - fiber._debugOwner = null; +function commitPassiveMountEffects_begin(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; + + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitPassiveMountEffects_complete(subtreeRoot, root); + } } } -function emptyPortalContainer(current) { - var portal = current.stateNode; - var containerInfo = portal.containerInfo; - var emptyChildSet = createContainerChildSet(containerInfo); -} +function commitPassiveMountEffects_complete(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; -function commitContainer(finishedWork) { - switch (finishedWork.tag) { - case ClassComponent: - case HostComponent: - case HostText: - case FundamentalComponent: { + if ((fiber.flags & Passive) !== NoFlags) { + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitPassiveMountOnFiber, + null, + root, + fiber + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); + } + } + + if (fiber === subtreeRoot) { + nextEffect = null; return; } - case HostRoot: - case HostPortal: { - var portalOrRoot = finishedWork.stateNode; - var containerInfo = portalOrRoot.containerInfo, - pendingChildren = portalOrRoot.pendingChildren; + var sibling = fiber.sibling; + + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; return; } - } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + nextEffect = fiber.return; } } -function commitDeletion(finishedRoot, current, renderPriorityLevel) { - { - // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current); - } - - var alternate = current.alternate; - detachFiberMutation(current); +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); + } - if (alternate !== null) { - detachFiberMutation(alternate); + break; + } } } -function commitWork(current, finishedWork) { - { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - // Layout effects are destroyed during the mutation phase so that all - // destroy functions for all fibers are called before any create functions. - // This prevents sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. +function commitPassiveUnmountEffects(firstChild) { + nextEffect = firstChild; + commitPassiveUnmountEffects_begin(); +} + +function commitPassiveUnmountEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; + var child = fiber.child; + + if ((nextEffect.flags & ChildDeletion) !== NoFlags) { + var deletions = fiber.deletions; + + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + nextEffect = fiberToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + fiberToDelete, + fiber + ); + } + { - commitHookEffectListUnmount(Layout | HasEffect, finishedWork); + // A fiber was deleted from this parent fiber, but it's still part of + // the previous (alternate) parent fiber's list of children. Because + // children are a linked list, an earlier sibling that's still alive + // will be connected to the deleted fiber via its `alternate`: + // + // live fiber + // --alternate--> previous live fiber + // --sibling--> deleted fiber + // + // We can't disconnect `alternate` on nodes that haven't been deleted + // yet, but we can disconnect the `sibling` and `child` pointers. + var previousFiber = fiber.alternate; + + if (previousFiber !== null) { + var detachedChild = previousFiber.child; + + if (detachedChild !== null) { + previousFiber.child = null; + + do { + var detachedSibling = detachedChild.sibling; + detachedChild.sibling = null; + detachedChild = detachedSibling; + } while (detachedChild !== null); + } + } } - return; + nextEffect = fiber; } + } - case Profiler: { - return; - } + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffects_complete(); + } + } +} - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; - } +function commitPassiveUnmountEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } + if ((fiber.flags & Passive) !== NoFlags) { + setCurrentFiber(fiber); + commitPassiveUnmountOnFiber(fiber); + resetCurrentFiber(); + } - case HostRoot: { - break; - } + var sibling = fiber.sibling; - case OffscreenComponent: - case LegacyHiddenComponent: { - return; - } + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - commitContainer(finishedWork); - return; + nextEffect = fiber.return; } } -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; +function commitPassiveUnmountOnFiber(finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount( + Passive$1 | HasEffect, + finishedWork, + finishedWork.return + ); + } - if (newState !== null) { - markCommitTimeOfFallback(); + break; + } } } -function attachSuspenseRetryListeners(finishedWork) { - // If this boundary just timed out, then it will have a set of wakeables. - // For each wakeable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. - var wakeables = finishedWork.updateQueue; +function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + deletedSubtreeRoot, + nearestMountedAncestor +) { + while (nextEffect !== null) { + var fiber = nextEffect; // Deletion effects fire in parent -> child order + // TODO: Check if fiber has a PassiveStatic flag - if (wakeables !== null) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we + // do this, still need to handle `deletedTreeCleanUpLevel` correctly.) - if (retryCache === null) { - retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + if (child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ); } + } +} - wakeables.forEach(function(wakeable) { - // Memoize using the boundary fiber to prevent redundant listeners. - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - - if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } +function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot +) { + while (nextEffect !== null) { + var fiber = nextEffect; + var sibling = fiber.sibling; + var returnFiber = fiber.return; - retryCache.add(wakeable); - wakeable.then(retry, retry); + { + // This is the default branch (level 0). We do not recursively clear all + // the fiber fields. Only the root of the deleted subtree. + if (fiber === deletedSubtreeRoot) { + detachFiberAfterEffects(fiber); + nextEffect = null; + return; } - }); + } + + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, returnFiber); + nextEffect = sibling; + return; + } + + nextEffect = returnFiber; } -} // This function detects when a Suspense boundary goes from visible to hidden. -// It returns false if the boundary is already hidden. -// TODO: Use an effect tag. +} -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - if (current !== null) { - var oldState = current.memoizedState; +function commitPassiveUnmountInsideDeletedTreeOnFiber( + current, + nearestMountedAncestor +) { + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); + } - if (oldState === null || oldState.dehydrated !== null) { - var newState = finishedWork.memoizedState; - return newState !== null && newState.dehydrated === null; + break; } } +} - return false; +var didWarnWrongReturnPointer = false; + +function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { + { + if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { + didWarnWrongReturnPointer = true; + + error( + "Internal React error: Return pointer is inconsistent " + "with parent." + ); + } + } // TODO: Remove this assignment once we're confident that it won't break + // anything, by checking the warning logs for the above invariant + + fiber.return = expectedReturnFiber; } var COMPONENT_TYPE = 0; @@ -16900,6 +17933,7 @@ if (typeof Symbol === "function" && Symbol.for) { var ceil = Math.ceil; var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ @@ -16907,21 +17941,18 @@ var NoContext = var BatchedContext = /* */ 1; -var DiscreteEventContext = - /* */ - 4; var LegacyUnbatchedContext = /* */ - 8; + 4; var RenderContext = /* */ - 16; + 8; var CommitContext = /* */ - 32; + 16; var RetryAfterError = /* */ - 64; + 32; var RootIncomplete = 0; var RootFatalErrored = 1; var RootErrored = 2; @@ -16961,8 +17992,7 @@ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. -var workInProgressRootPingedLanes = NoLanes; -var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train +var workInProgressRootPingedLanes = NoLanes; // The most recent time we committed a fallback. This lets us ensure a train // model where we don't commit new loading states in too quick succession. var globalMostRecentFallbackTime = 0; @@ -16981,40 +18011,26 @@ function resetRenderTimer() { function getRenderTargetTime() { return workInProgressRootRenderTargetTime; } -var nextEffect = null; var hasUncaughtError = false; var firstUncaughtError = null; -var legacyErrorBoundariesThatAlreadyFailed = null; +var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; -var pendingPassiveEffectsRenderPriority = NoPriority$1; var pendingPassiveEffectsLanes = NoLanes; -var pendingPassiveHookEffectsMount = []; -var pendingPassiveHookEffectsUnmount = []; -var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; var nestedUpdateCount = 0; var rootWithNestedUpdates = null; var NESTED_PASSIVE_UPDATE_LIMIT = 50; -var nestedPassiveUpdateCount = 0; // Marks the need to reschedule pending interactions at these lanes -// 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. -// TODO: Can use a bitmask instead of an array - -var spawnedWorkDuringRender = null; // If two updates are scheduled within the same event, we should treat their +var nestedPassiveUpdateCount = 0; // If two updates are scheduled within the same event, we should treat their // event times as simultaneous, even if the actual clock time has advanced // between the first and second call. var currentEventTime = NoTimestamp; -var currentEventWipLanes = NoLanes; -var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. +var currentEventTransitionLane = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. // We warn about state updates for unmounted components differently in this case. var isFlushingPassiveEffects = false; -var focusedInstanceHandle = null; -var shouldFireAfterActiveInstanceBlur = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -17036,69 +18052,46 @@ function requestUpdateLane(fiber) { // Special cases var mode = fiber.mode; - if ((mode & BlockingMode) === NoMode) { + if ((mode & ConcurrentMode) === NoMode) { return SyncLane; - } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 - ? SyncLane - : SyncBatchedLane; - } // The algorithm for assigning an update to a lane should be stable for all - // updates at the same priority within the same event. To do this, the inputs - // to the algorithm must be the same. For example, we use the `renderLanes` - // to avoid choosing a lane that is already in the middle of rendering. - // - // However, the "included" lanes could be mutated in between updates in the - // same event, like if you perform an update inside `flushSync`. Or any other - // code path that might call `prepareFreshStack`. - // - // The trick we use is to cache the first of each of these inputs within an - // event. Then reset the cached values once we can be sure the event is over. - // Our heuristic for that is whenever we enter a concurrent work loop. - // - // We'll do the same for `currentEventPendingLanes` below. - - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; } var isTransition = requestCurrentTransition() !== NoTransition; if (isTransition) { - if (currentEventPendingLanes !== NoLanes) { - currentEventPendingLanes = - mostRecentlyUpdatedRoot !== null - ? mostRecentlyUpdatedRoot.pendingLanes - : NoLanes; + // The algorithm for assigning an update to a lane should be stable for all + // updates at the same priority within the same event. To do this, the + // inputs to the algorithm must be the same. + // + // The trick we use is to cache the first of each of these inputs within an + // event. Then reset the cached values once we can be sure the event is + // over. Our heuristic for that is whenever we enter a concurrent work loop. + if (currentEventTransitionLane === NoLane) { + // All transitions within the same event are assigned the same lane. + currentEventTransitionLane = claimNextTransitionLane(); } - return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); - } // TODO: Remove this dependency on the Scheduler priority. - // To do that, we're replacing it with an update lane priority. - - var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. - // This couples React to the Scheduler internals, so we're replacing it - // with the currentUpdateLanePriority above. As an example of how this - // could be problematic, if we're not inside `Scheduler.runWithPriority`, - // then we'll get the priority of the current running Scheduler task, - // which is probably not what we want. - - var lane; + return currentEventTransitionLane; + } // Updates originating inside certain React methods, like flushSync, have + // their priority set by tracking it with a context variable. + // + // The opaque type returned by the host config is internally a lane, so we can + // use that directly. + // TODO: Move this type conversion to the event priority module. - if ( - // TODO: Temporary. We're removing the concept of discrete updates. - (executionContext & DiscreteEventContext) !== NoContext && - schedulerPriority === UserBlockingPriority$1 - ) { - lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); - } else { - var schedulerLanePriority = schedulerPriorityToLanePriority( - schedulerPriority - ); + var updateLane = getCurrentUpdatePriority(); - lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); - } + if (updateLane !== NoLane) { + return updateLane; + } // This update originated outside React. Ask the host environement for an + // appropriate priority, based on the type of event. + // + // The opaque type returned by the host config is internally a lane, so we can + // use that directly. + // TODO: Move this type conversion to the event priority module. - return lane; + var eventLane = getCurrentEventPriority(); + return eventLane; } function requestRetryLane(fiber) { @@ -17108,19 +18101,11 @@ function requestRetryLane(fiber) { // Special cases var mode = fiber.mode; - if ((mode & BlockingMode) === NoMode) { + if ((mode & ConcurrentMode) === NoMode) { return SyncLane; - } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 - ? SyncLane - : SyncBatchedLane; - } // See `requestUpdateLane` for explanation of `currentEventWipLanes` - - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; } - return findRetryLane(currentEventWipLanes); + return claimNextRetryLane(); } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -17131,7 +18116,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (root === null) { warnAboutUpdateOnUnmountedFiberInDEV(fiber); return null; - } // Mark that the root has a pending update. + } markRootUpdated(root, lane, eventTime); @@ -17157,10 +18142,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { // already started rendering. markRootSuspended$1(root, workInProgressRootRenderLanes); } - } // TODO: requestUpdateLanePriority also reads the priority. Pass the - // priority as an argument to that function and this one. - - var priorityLevel = getCurrentPriorityLevel(); + } if (lane === SyncLane) { if ( @@ -17168,52 +18150,32 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { (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, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed + // 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. - performSyncWorkOnRoot(root); } else { ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, lane); - if (executionContext === NoContext) { + if ( + executionContext === NoContext && + (fiber.mode & ConcurrentMode) === NoMode + ) { // Flush the synchronous work now, unless 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-initiated // updates, to preserve historical behavior of legacy mode. resetRenderTimer(); - flushSyncCallbackQueue(); + flushSyncCallbacksOnlyInLegacyMode(); } } } else { - // Schedule a discrete update but only if it's not Sync. - if ( - (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered - // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority$1 || - priorityLevel === ImmediatePriority$1) - ) { - // 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 Set([root]); - } else { - rootsWithPendingDiscreteUpdates.add(root); - } - } // Schedule other updates after in case the callback is sync. - + // Schedule other updates after in case the callback is sync. ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, lane); - } // We use this when assigning a lane for a transition inside - // `requestUpdateLane`. We assume it's the same as the root being updated, - // since in the common case of a single root app it probably is. If it's not - // the same root, then it's not a huge deal, we just might batch more stuff - // together more than necessary. - - mostRecentlyUpdatedRoot = root; + } + + return root; } // This is split into a separate function so we can mark a fiber with pending // work without treating it as a typical update that originates from an event; // e.g. retrying a Suspense boundary isn't an update, but it does schedule work @@ -17235,7 +18197,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { ) { warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - } // Walk the parent path to the root and update the child expiration time. + } // Walk the parent path to the root and update the child lanes. var node = sourceFiber; var parent = sourceFiber.return; @@ -17264,6 +18226,20 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { } else { return null; } +} + +function isInterleavedUpdate(fiber, lane) { + return ( + // TODO: Optimize slightly by comparing to root that fiber belongs to. + // Requires some refactoring. Not a big deal though since it's rare for + // concurrent apps to have more than a single root. + workInProgressRoot !== null && + (fiber.mode & ConcurrentMode) !== NoMode && // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps), + // then don't treat this as an interleaved update. This pattern is + // accompanied by a warning but we haven't fully deprecated it yet. We can + // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled. + deferRenderPhaseUpdateToNextBatch + ); } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the priority // of the existing task is the same as the priority of the next level that the @@ -17279,50 +18255,88 @@ function ensureRootIsScheduled(root, currentTime) { var nextLanes = getNextLanes( root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes - ); // This returns the priority level computed during the `getNextLanes` call. - - var newCallbackPriority = returnNextLanesPriority(); + ); if (nextLanes === NoLanes) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); - root.callbackNode = null; - root.callbackPriority = NoLanePriority; } + root.callbackNode = null; + root.callbackPriority = NoLane; return; - } // Check if there's an existing task. We may be able to reuse it. + } // We use the highest priority lane to represent the priority of the callback. - if (existingCallbackNode !== null) { - var existingCallbackPriority = root.callbackPriority; + var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it. - if (existingCallbackPriority === newCallbackPriority) { - // The priority hasn't changed. We can reuse the existing task. Exit. - return; - } // The priority changed. Cancel the existing callback. We'll schedule a new - // one below. + var existingCallbackPriority = root.callbackPriority; + + if (existingCallbackPriority === newCallbackPriority) { + { + // If we're going to re-use an existing task, it needs to exist. + // Assume that discrete update microtasks are non-cancellable and null. + // TODO: Temporary until we confirm this warning is not fired. + if ( + existingCallbackNode == null && + existingCallbackPriority !== SyncLane + ) { + error( + "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue." + ); + } + } // The priority hasn't changed. We can reuse the existing task. Exit. + + return; + } + if (existingCallbackNode != null) { + // Cancel the existing callback. We'll schedule a new one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. var newCallbackNode; - if (newCallbackPriority === SyncLanePriority) { + if (newCallbackPriority === SyncLane) { // Special case: Sync React callbacks are scheduled on a special // internal queue - newCallbackNode = scheduleSyncCallback( - performSyncWorkOnRoot.bind(null, root) - ); - } else if (newCallbackPriority === SyncBatchedLanePriority) { - newCallbackNode = scheduleCallback( - ImmediatePriority$1, - performSyncWorkOnRoot.bind(null, root) - ); + if (root.tag === LegacyRoot) { + scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else { + scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + } + + { + // Flush the queue in an Immediate task. + scheduleCallback(ImmediatePriority, flushSyncCallbacks); + } + + newCallbackNode = null; } else { - var schedulerPriorityLevel = lanePriorityToSchedulerPriority( - newCallbackPriority - ); + var schedulerPriorityLevel; + + switch (lanesToEventPriority(nextLanes)) { + case DiscreteEventPriority: + schedulerPriorityLevel = ImmediatePriority; + break; + + case ContinuousEventPriority: + schedulerPriorityLevel = UserBlockingPriority; + break; + + case DefaultEventPriority: + schedulerPriorityLevel = NormalPriority; + break; + + case IdleEventPriority: + schedulerPriorityLevel = IdlePriority; + break; + + default: + schedulerPriorityLevel = NormalPriority; + break; + } + newCallbackNode = scheduleCallback( schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root) @@ -17334,12 +18348,11 @@ function ensureRootIsScheduled(root, currentTime) { } // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root) { - // Since we know we're in a React event, we can clear the current +function performConcurrentWorkOnRoot(root, didTimeout) { // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; + currentEventTransitionLane = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { throw Error("Should not already be working."); @@ -17369,40 +18382,41 @@ function performConcurrentWorkOnRoot(root) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; - } - - var exitStatus = renderRootConcurrent(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack(root, NoLanes); - } else if (exitStatus !== RootIncomplete) { + } // We disable time-slicing in some cases: if the work has been CPU-bound + // for too long ("expired" work, to prevent starvation), or we're in + // sync-updates-by-default mode. + // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + + var exitStatus = + shouldTimeSlice(root, lanes) && !didTimeout + ? renderRootConcurrent(root, lanes) + : renderRootSync(root, lanes); + + if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. if (root.hydrate) { root.hydrate = false; + + { + errorHydratingContainer(root.containerInfo); + } + clearContainer(root.containerInfo); } // If something threw an error, try rendering one more time. We'll render // synchronously to block concurrent data mutations, and we'll includes // all pending updates are included. If it still fails after the second // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { - exitStatus = renderRootSync(root, lanes); + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = renderRootSync(root, errorRetryLanes); } } @@ -17567,55 +18581,37 @@ function performSyncWorkOnRoot(root) { } flushPassiveEffects(); - var lanes; - var exitStatus; - - if ( - root === workInProgressRoot && - includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes) - ) { - // There's a partial tree, and at least one of its lanes has expired. Finish - // rendering it before rendering the rest of the expired work. - lanes = workInProgressRootRenderLanes; - exitStatus = renderRootSync(root, lanes); + var lanes = getNextLanes(root, NoLanes); - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // Note that this only happens when part of the tree is rendered - // concurrently. If the whole tree is rendered synchronously, then there - // are no interleaved events. - lanes = getNextLanes(root, lanes); - exitStatus = renderRootSync(root, lanes); - } - } else { - lanes = getNextLanes(root, NoLanes); - exitStatus = renderRootSync(root, lanes); + if (!includesSomeLane(lanes, SyncLane)) { + // There's no remaining sync work left. + ensureRootIsScheduled(root, now()); + return null; } + var exitStatus = renderRootSync(root, lanes); + if (root.tag !== LegacyRoot && exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. if (root.hydrate) { root.hydrate = false; + + { + errorHydratingContainer(root.containerInfo); + } + clearContainer(root.containerInfo); } // If something threw an error, try rendering one more time. We'll render // synchronously to block concurrent data mutations, and we'll includes // all pending updates are included. If it still fails after the second // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; exitStatus = renderRootSync(root, lanes); } } @@ -17638,7 +18634,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } - function batchedUpdates$1(fn, a) { var prevExecutionContext = executionContext; executionContext |= BatchedContext; @@ -17646,45 +18641,47 @@ function batchedUpdates$1(fn, a) { try { return fn(a); } finally { - executionContext = prevExecutionContext; + executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer + // most batchedUpdates-like method. if (executionContext === NoContext) { - // Flush the immediate callbacks that were scheduled during this batch resetRenderTimer(); - flushSyncCallbackQueue(); + flushSyncCallbacksOnlyInLegacyMode(); } } } function flushSync(fn, a) { var prevExecutionContext = executionContext; - - if ((prevExecutionContext & (RenderContext | CommitContext)) !== NoContext) { - { - error( - "flushSync was called from inside a lifecycle method. React cannot " + - "flush when React is already rendering. Consider moving this call to " + - "a scheduler task or micro task." - ); - } - - return fn(a); - } - executionContext |= BatchedContext; + var prevTransition = ReactCurrentBatchConfig$2.transition; + var previousPriority = getCurrentUpdatePriority(); - { - try { - if (fn) { - return runWithPriority(ImmediatePriority$1, fn.bind(null, a)); - } else { - return undefined; - } - } finally { - 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. + try { + ReactCurrentBatchConfig$2.transition = 0; + setCurrentUpdatePriority(DiscreteEventPriority); - flushSyncCallbackQueue(); + if (fn) { + return fn(a); + } else { + return undefined; + } + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; + 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. + + if ((executionContext & (RenderContext | CommitContext)) === NoContext) { + flushSyncCallbacks(); + } else { + { + error( + "flushSync was called from inside a lifecycle method. React cannot " + + "flush when React is already rendering. Consider moving this call to " + + "a scheduler task or micro task." + ); + } } } } @@ -17731,10 +18728,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootSkippedLanes = NoLanes; workInProgressRootUpdatedLanes = NoLanes; workInProgressRootPingedLanes = NoLanes; - - { - spawnedWorkDuringRender = null; - } + enqueueInterleavedUpdates(); { ReactStrictModeWarnings.discardPendingWarnings(); @@ -17824,20 +18818,6 @@ function popDispatcher(prevDispatcher) { ReactCurrentDispatcher$2.current = prevDispatcher; } -function pushInteractions(root) { - { - var prevInteractions = tracing.__interactionsRef.current; - tracing.__interactionsRef.current = root.memoizedInteractions; - return prevInteractions; - } -} - -function popInteractions(prevInteractions) { - { - tracing.__interactionsRef.current = prevInteractions; - } -} - function markCommitTimeOfFallback() { globalMostRecentFallbackTime = now(); } @@ -17897,11 +18877,8 @@ function renderRootSync(root, lanes) { if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { prepareFreshStack(root, lanes); - startWorkOnPendingInteractions(root, lanes); } - var prevInteractions = pushInteractions(root); - do { try { workLoopSync(); @@ -17912,11 +18889,6 @@ function renderRootSync(root, lanes) { } while (true); resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - executionContext = prevExecutionContext; popDispatcher(prevDispatcher); @@ -17952,11 +18924,8 @@ function renderRootConcurrent(root, lanes) { if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { resetRenderTimer(); prepareFreshStack(root, lanes); - startWorkOnPendingInteractions(root, lanes); } - var prevInteractions = pushInteractions(root); - do { try { workLoopConcurrent(); @@ -17967,11 +18936,6 @@ function renderRootConcurrent(root, lanes) { } while (true); resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - popDispatcher(prevDispatcher); executionContext = prevExecutionContext; @@ -18054,47 +19018,6 @@ function completeUnitOfWork(unitOfWork) { workInProgress = next; return; } - - resetChildLanes(completedWork); - - if ( - returnFiber !== null && // Do not append effects to parents if a sibling failed to complete - (returnFiber.flags & Incomplete) === NoFlags - ) { - // Append all the effects of the subtree and this fiber onto the effect - // list of the parent. The completion order of the children affects the - // side-effect order. - if (returnFiber.firstEffect === null) { - returnFiber.firstEffect = completedWork.firstEffect; - } - - if (completedWork.lastEffect !== null) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork.firstEffect; - } - - returnFiber.lastEffect = completedWork.lastEffect; - } // If this fiber had side-effects, we append it AFTER the children's - // side-effects. We can perform certain side-effects earlier if needed, - // by doing multiple passes over the effect list. We don't want to - // schedule our own side-effect on our own list because if end up - // reusing children we'll schedule this effect onto itself since we're - // at the end. - - var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect - // list. PerformedWork effect is read by React DevTools but shouldn't be - // committed. - - if (flags > PerformedWork) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork; - } else { - returnFiber.firstEffect = completedWork; - } - - returnFiber.lastEffect = completedWork; - } - } } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -18127,9 +19050,10 @@ function completeUnitOfWork(unitOfWork) { } if (returnFiber !== null) { - // Mark the parent fiber as incomplete and clear its effect list. - returnFiber.firstEffect = returnFiber.lastEffect = null; + // Mark the parent fiber as incomplete and clear its subtree flags. returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags; + returnFiber.deletions = null; } } @@ -18151,90 +19075,21 @@ function completeUnitOfWork(unitOfWork) { } } -function resetChildLanes(completedWork) { - if ( - // TODO: Move this check out of the hot path by moving `resetChildLanes` - // to switch statement in `completeWork`. - (completedWork.tag === LegacyHiddenComponent || - completedWork.tag === OffscreenComponent) && - completedWork.memoizedState !== null && - !includesSomeLane(subtreeRenderLanes, OffscreenLane) && - (completedWork.mode & ConcurrentMode) !== NoLanes - ) { - // The children of this component are hidden. Don't bubble their - // expiration times. - return; - } - - var newChildLanes = NoLanes; // Bubble up the earliest expiration time. - - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var actualDuration = completedWork.actualDuration; - var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will - // only be updated if work is done on the fiber (i.e. it doesn't bailout). - // When work is done, it should bubble to the parent's actualDuration. If - // the fiber has not been cloned though, (meaning no work was done), then - // this value will reflect the amount of time spent working on a previous - // render. In that case it should not bubble. We determine whether it was - // cloned by comparing the child pointer. - - var shouldBubbleActualDurations = - completedWork.alternate === null || - completedWork.child !== completedWork.alternate.child; - var child = completedWork.child; - - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - - if (shouldBubbleActualDurations) { - actualDuration += child.actualDuration; - } - - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - var isTimedOutSuspense = - completedWork.tag === SuspenseComponent && - completedWork.memoizedState !== null; - - if (isTimedOutSuspense) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var primaryChildFragment = completedWork.child; - - if (primaryChildFragment !== null) { - treeBaseDuration -= primaryChildFragment.treeBaseDuration; - } - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; +function commitRoot(root) { + // TODO: This no longer makes any sense. We already wrap the mutation and + // layout phases. Should be able to remove. + var previousUpdateLanePriority = getCurrentUpdatePriority(); + var prevTransition = ReactCurrentBatchConfig$2.transition; - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - _child = _child.sibling; - } + try { + ReactCurrentBatchConfig$2.transition = 0; + setCurrentUpdatePriority(DiscreteEventPriority); + commitRootImpl(root, previousUpdateLanePriority); + } finally { + ReactCurrentBatchConfig$2.transition = prevTransition; + setCurrentUpdatePriority(previousUpdateLanePriority); } - completedWork.childLanes = newChildLanes; -} - -function commitRoot(root) { - var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority( - ImmediatePriority$1, - commitRootImpl.bind(null, root, renderPriorityLevel) - ); return null; } @@ -18260,6 +19115,15 @@ function commitRootImpl(root, renderPriorityLevel) { if (finishedWork === null) { return null; + } else { + { + if (lanes === NoLanes) { + error( + "root.finishedLanes should not be empty during a commit. This is a " + + "bug in React." + ); + } + } } root.finishedWork = null; @@ -18272,52 +19136,57 @@ function commitRootImpl(root, renderPriorityLevel) { } // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. - root.callbackNode = null; // Update the first and last pending times on this root. The new first + root.callbackNode = null; + root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); - markRootFinished(root, remainingLanes); // Clear already finished discrete updates in case that a later call of - // `flushDiscreteUpdates` starts a useless render pass which may cancels - // a scheduled timeout. - - if (rootsWithPendingDiscreteUpdates !== null) { - if ( - !hasDiscreteLanes(remainingLanes) && - rootsWithPendingDiscreteUpdates.has(root) - ) { - rootsWithPendingDiscreteUpdates.delete(root); - } - } + markRootFinished(root, remainingLanes); if (root === workInProgressRoot) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; workInProgressRootRenderLanes = NoLanes; - } // Get the list of effects. - - var firstEffect; - - if (finishedWork.flags > PerformedWork) { - // A fiber's effect list consists only of its children, not itself. So if - // the root has an effect, we need to add it to the end of the list. The - // resulting list is the set that would belong to the root's parent, if it - // had one; that is, all the effects in the tree including the root. - if (finishedWork.lastEffect !== null) { - finishedWork.lastEffect.nextEffect = finishedWork; - firstEffect = finishedWork.firstEffect; - } else { - firstEffect = finishedWork; - } - } else { - // There is no effect on the root. - firstEffect = finishedWork.firstEffect; - } + } // If there are pending passive effects, schedule a callback to process them. + // Do this as early as possible, so it is queued before anything else that + // might get scheduled in the commit phase. (See #16714.) + // TODO: Delete all other places that schedule the passive effect callback + // They're redundant. - if (firstEffect !== null) { + if ( + (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || + (finishedWork.flags & PassiveMask) !== NoFlags + ) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + }); + } + } // Check if there are any effects in the whole tree. + // TODO: This is left over from the effect list implementation, where we had + // to check for the existence of `firstEffect` to satsify Flow. I think the + // only other reason this optimization exists is because it affects profiling. + // Reconsider whether this is necessary. + + var subtreeHasEffects = + (finishedWork.subtreeFlags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + var rootHasEffect = + (finishedWork.flags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + + if (subtreeHasEffects || rootHasEffect) { + var prevTransition = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority(DiscreteEventPriority); var prevExecutionContext = executionContext; - executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles + executionContext |= CommitContext; // Reset this to null before calling lifecycles ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass // of the effect list for each phase: all mutation effects come before all @@ -18326,58 +19195,18 @@ function commitRootImpl(root, renderPriorityLevel) { // state of the host tree right before we mutate it. This is where // getSnapshotBeforeUpdate is called. - focusedInstanceHandle = prepareForCommit(root.containerInfo); - shouldFireAfterActiveInstanceBlur = false; - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitBeforeMutationEffects, null); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); // We no longer need to track the active instance fiber - - focusedInstanceHandle = null; + var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects( + root, + finishedWork + ); { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); - } // The next phase is the mutation phase, where we mutate the host tree. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback( - null, - commitMutationEffects, - null, - root, - renderPriorityLevel - ); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error = clearCaughtError(); + } - captureCommitPhaseError(nextEffect, _error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); + commitMutationEffects(root, finishedWork); resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after // the mutation phase, so that the previous tree is still current during @@ -18385,38 +19214,15 @@ function commitRootImpl(root, renderPriorityLevel) { // work is current during componentDidMount/Update. root.current = finishedWork; // The next phase is the layout phase, where we call effects that read - // the host tree after it's been mutated. The idiomatic use case for this is - // layout, but class component lifecycles also fire here for legacy reasons. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error2 = clearCaughtError(); - - captureCommitPhaseError(nextEffect, _error2); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); - nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an + commitLayoutEffects(finishedWork, root, lanes); // opportunity to paint. requestPaint(); + executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value. - { - popInteractions(prevInteractions); - } - - executionContext = prevExecutionContext; + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; } else { // No effects. root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were @@ -18428,71 +19234,25 @@ function commitRootImpl(root, renderPriorityLevel) { } } - 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. rootDoesHavePassiveEffects = false; rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; - pendingPassiveEffectsRenderPriority = renderPriorityLevel; - } else { - // We are done with the effect chain at this point so let's clear the - // nextEffect pointers to assist with GC. If we have passive effects, we'll - // clear this in flushPassiveEffects. - nextEffect = firstEffect; - - while (nextEffect !== null) { - var nextNextEffect = nextEffect.nextEffect; - nextEffect.nextEffect = null; - - if (nextEffect.flags & Deletion) { - detachFiberAfterEffects(nextEffect); - } - - nextEffect = nextNextEffect; - } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root - if (remainingLanes !== NoLanes) { - { - if (spawnedWorkDuringRender !== null) { - var expirationTimes = spawnedWorkDuringRender; - spawnedWorkDuringRender = null; - - for (var i = 0; i < expirationTimes.length; i++) { - scheduleInteractions( - root, - expirationTimes[i], - root.memoizedInteractions - ); - } - } - - schedulePendingInteractions(root, remainingLanes); - } - } else { + if (remainingLanes === NoLanes) { // If there's no remaining work, we can clear the set of already failed // error boundaries. legacyErrorBoundariesThatAlreadyFailed = null; } - { - 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, lanes); - } - } - - if (remainingLanes === SyncLane) { - // Count the number of times the root synchronously re-renders without + if (includesSomeLane(remainingLanes, SyncLane)) { // finishing. If there are too many, it indicates an infinite update loop. + if (root === rootWithNestedUpdates) { nestedUpdateCount++; } else { @@ -18510,211 +19270,63 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var _error3 = firstUncaughtError; + var error$1 = firstUncaughtError; firstUncaughtError = null; - throw _error3; - } - - if ((executionContext & LegacyUnbatchedContext) !== NoContext) { - // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired - // synchronously, but layout updates should be deferred until the end - // of the batch. - - return null; - } // If layout work was scheduled, flush it now. - - flushSyncCallbackQueue(); - - return null; -} - -function commitBeforeMutationEffects() { - while (nextEffect !== null) { - var current = nextEffect.alternate; - - if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { - if ((nextEffect.flags & Deletion) !== NoFlags) { - if (doesFiberContain(nextEffect, focusedInstanceHandle)) { - shouldFireAfterActiveInstanceBlur = true; - } - } else { - // TODO: Move this out of the hot path using a dedicated effect tag. - if ( - nextEffect.tag === SuspenseComponent && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) - ) { - shouldFireAfterActiveInstanceBlur = true; - } - } - } - - var flags = nextEffect.flags; - - if ((flags & Snapshot) !== NoFlags) { - setCurrentFiber(nextEffect); - commitBeforeMutationLifeCycles(current, nextEffect); - resetCurrentFiber(); - } - - if ((flags & Passive) !== NoFlags) { - // If there are passive effects, schedule a callback to flush at - // the earliest opportunity. - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } - } - - nextEffect = nextEffect.nextEffect; - } -} - -function commitMutationEffects(root, renderPriorityLevel) { - // TODO: Should probably move the bulk of this function to commitWork. - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & Ref) { - var current = nextEffect.alternate; - - if (current !== null) { - commitDetachRef(current); - } - } // The following switch statement is only concerned about placement, - // updates, and deletions. To avoid needing to add a case for every possible - // bitmap value, we remove the secondary effects from the effect tag and - // switch on that value. - - var primaryFlags = flags & (Placement | Update | Deletion | Hydrating); - - switch (primaryFlags) { - case Placement: { - // inserted, before any life-cycles like componentDidMount gets called. - // TODO: findDOMNode doesn't rely on this any more but isMounted does - // and isMounted is deprecated anyway so we should be able to kill this. - - nextEffect.flags &= ~Placement; - break; - } - - case PlacementAndUpdate: { - // inserted, before any life-cycles like componentDidMount gets called. - - nextEffect.flags &= ~Placement; // Update - - var _current = nextEffect.alternate; - commitWork(_current, nextEffect); - break; - } - - case Hydrating: { - nextEffect.flags &= ~Hydrating; - break; - } - - case HydratingAndUpdate: { - nextEffect.flags &= ~Hydrating; // Update - - var _current2 = nextEffect.alternate; - commitWork(_current2, nextEffect); - break; - } - - case Update: { - var _current3 = nextEffect.alternate; - commitWork(_current3, nextEffect); - break; - } - - case Deletion: { - commitDeletion(root, nextEffect); - break; - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; + throw error$1; } -} -function commitLayoutEffects(root, committedLanes) { - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; + if ((executionContext & LegacyUnbatchedContext) !== NoContext) { + // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired + // synchronously, but layout updates should be deferred until the end + // of the batch. - if (flags & (Update | Callback)) { - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); - } + return null; + } // If the passive effects are the result of a discrete render, flush them + // synchronously at the end of the current task so that the result is + // immediately observable. Otherwise, we assume that they are not + // order-dependent and do not need to be observed by external systems, so we + // can wait until after paint. + // TODO: We can optimize this by not scheduling the callback earlier. Since we + // currently schedule the callback in multiple places, will wait until those + // are consolidated. - { - if (flags & Ref) { - commitAttachRef(nextEffect); - } - } + if ( + includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && + root.tag !== LegacyRoot + ) { + flushPassiveEffects(); + } // If layout work was scheduled, flush it now. - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } + flushSyncCallbacks(); + + return null; } function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { - var priorityLevel = - pendingPassiveEffectsRenderPriority > NormalPriority$1 - ? NormalPriority$1 - : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoPriority$1; + // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should + // probably just combine the two functions. I believe they were only separate + // in the first place because we used to wrap it with + // `Scheduler.runWithPriority`, which accepts a function. But now we track the + // priority within React itself, so we can mutate the variable directly. + if (rootWithPendingPassiveEffects !== null) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes); + var priority = lowerEventPriority(DefaultEventPriority, renderPriority); + var prevTransition = ReactCurrentBatchConfig$2.transition; + var previousPriority = getCurrentUpdatePriority(); - { - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); + try { + ReactCurrentBatchConfig$2.transition = 0; + setCurrentUpdatePriority(priority); + return flushPassiveEffectsImpl(); + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; } } return false; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - - { - fiber.flags |= PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags |= PassiveUnmountPendingDev; - } - } - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} - -function invokePassiveEffectCreate(effect) { - var create = effect.create; - effect.destroy = create(); -} function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { @@ -18722,8 +19334,10 @@ function flushPassiveEffectsImpl() { } var root = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; - rootWithPendingPassiveEffects = null; + rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects. + // Figure out why and fix it. It's not causing any known issues (probably + // because it's only used for profiling), but it's a refactor hazard. + pendingPassiveEffectsLanes = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -18736,113 +19350,22 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called - // before ANY passive effect create functions are called. - // Otherwise effects in sibling components might interfere with each other. - // e.g. a destroy function in one component may unintentionally override a ref - // value set by a create function in another component. - // Layout effects have the same constraint. - // First pass: Destroy stale passive effects. - - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - - for (var i = 0; i < unmountEffects.length; i += 2) { - var _effect = unmountEffects[i]; - var fiber = unmountEffects[i + 1]; - var destroy = _effect.destroy; - _effect.destroy = undefined; - - { - fiber.flags &= ~PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags &= ~PassiveUnmountPendingDev; - } - } - - if (typeof destroy === "function") { - { - setCurrentFiber(fiber); - - { - invokeGuardedCallback(null, destroy, null); - } - - if (hasCaughtError()) { - if (!(fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(fiber, error); - } - - resetCurrentFiber(); - } - } - } // Second pass: Create new passive effects. - - var mountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - - for (var _i = 0; _i < mountEffects.length; _i += 2) { - var _effect2 = mountEffects[_i]; - var _fiber = mountEffects[_i + 1]; - - { - setCurrentFiber(_fiber); - - { - invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); - } - - if (hasCaughtError()) { - if (!(_fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var _error4 = clearCaughtError(); - - captureCommitPhaseError(_fiber, _error4); - } - - resetCurrentFiber(); - } - } // Note: This currently assumes there are no passive effects on the root fiber - // because the root is not part of its own effect list. - // This could change in the future. - - var effect = root.current.firstEffect; - - while (effect !== null) { - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC - - effect.nextEffect = null; - - if (effect.flags & Deletion) { - detachFiberAfterEffects(effect); - } - - effect = nextNextEffect; - } - - { - popInteractions(prevInteractions); - finishPendingInteractions(root, lanes); - } + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects { isFlushingPassiveEffects = false; } executionContext = prevExecutionContext; - flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this + flushSyncCallbacks(); // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. nestedPassiveUpdateCount = - rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; + rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; // TODO: Move to commitPassiveMountEffects + + onPostCommitRoot(root); + return true; } @@ -18879,23 +19402,26 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { if (root !== null) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, SyncLane); } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); return; } - var fiber = sourceFiber.return; + var fiber = null; + + { + fiber = sourceFiber.return; + } while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -18906,7 +19432,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$1, sourceFiber); var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); enqueueUpdate(fiber, update); var eventTime = requestEventTime(); @@ -18915,25 +19441,6 @@ function captureCommitPhaseError(sourceFiber, error) { if (root !== null) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, SyncLane); - } else { - // This component has already been unmounted. - // We can't schedule any follow up work for the root because the fiber is already unmounted, - // but we can still call the log-only boundary so the error isn't swallowed. - // - // TODO This is only a temporary bandaid for the old reconciler fork. - // We can delete this special case once the new fork is merged. - if ( - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance) - ) { - try { - instance.componentDidCatch(error, errorInfo); - } catch (errorToIgnore) { - // TODO Ignore this error? Rethrow it? - // This is kind of an edge case. - } - } } return; @@ -18942,6 +19449,22 @@ function captureCommitPhaseError(sourceFiber, error) { fiber = fiber.return; } + + { + // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning + // will fire for errors that are thrown by destroy functions inside deleted + // trees. What it should instead do is propagate the error to the parent of + // the deleted tree. In the meantime, do not add this warning to the + // allowlist; this is only for our internal use. + error( + "Internal React error: Attempted to capture a commit phase error " + + "inside a detached tree. This indicates a bug in React. Likely " + + "causes include deleting the same fiber more than once, committing an " + + "already-finished tree, or an inconsistent return pointer.\n\n" + + "Error message:\n\n%s", + error$1 + ); + } } function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; @@ -18985,7 +19508,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { } ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, pingedLanes); } function retryTimedOutBoundary(boundaryFiber, retryLane) { @@ -18994,6 +19516,8 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { // suspended it has resolved, which means at least part of the tree was // likely unblocked. Try rendering again, at a new expiration time. if (retryLane === NoLane) { + // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? retryLane = requestRetryLane(boundaryFiber); } // TODO: Special case idle priority? @@ -19003,7 +19527,6 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { if (root !== null) { markRootUpdated(root, retryLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, retryLane); } } function resolveRetryWakeable(boundaryFiber, wakeable) { @@ -19093,7 +19616,7 @@ function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { return; } - if (!(fiber.mode & (BlockingMode | ConcurrentMode))) { + if (!(fiber.mode & ConcurrentMode)) { return; } @@ -19113,7 +19636,7 @@ function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. - var componentName = getComponentName(fiber.type) || "ReactComponent"; + var componentName = getComponentNameFromFiber(fiber) || "ReactComponent"; if (didWarnStateUpdateForNotYetMountedComponent !== null) { if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) { @@ -19162,15 +19685,33 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } // If there are pending passive effects unmounts for this Fiber, - // we can assume that they would have prevented this update. + } - if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { - return; + if ((fiber.flags & PassiveStatic) !== NoFlags) { + var updateQueue = fiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if (effect.destroy !== undefined) { + if ((effect.tag & Passive$1) !== NoFlags$1) { + return; + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. - var componentName = getComponentName(fiber.type) || "ReactComponent"; + var componentName = getComponentNameFromFiber(fiber) || "ReactComponent"; if (didWarnStateUpdateForUnmountedComponent !== null) { if (didWarnStateUpdateForUnmountedComponent.has(componentName)) { @@ -19254,14 +19795,23 @@ var beginWork$1; invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); if (hasCaughtError()) { - var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. - // Rethrow this error instead of the original one. + var replayError = clearCaughtError(); - throw replayError; - } else { - // This branch is reachable if the render phase is impure. - throw originalError; - } + if ( + typeof replayError === "object" && + replayError !== null && + replayError._suppressLogging && + typeof originalError === "object" && + originalError !== null && + !originalError._suppressLogging + ) { + // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. + originalError._suppressLogging = true; + } + } // We always throw the original error in case the second render pass is not idempotent. + // This can happen if a memoized function or CommonJS module doesn't throw after first invokation. + + throw originalError; } }; } @@ -19285,7 +19835,7 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) { case ForwardRef: case SimpleMemoComponent: { var renderingComponentName = - (workInProgress && getComponentName(workInProgress.type)) || + (workInProgress && getComponentNameFromFiber(workInProgress)) || "Unknown"; // Dedupe by the rendering component because it's the one that needs to be fixed. var dedupeKey = renderingComponentName; @@ -19293,7 +19843,7 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) { if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) { didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey); var setStateComponentName = - getComponentName(fiber.type) || "Unknown"; + getComponentNameFromFiber(fiber) || "Unknown"; error( "Cannot update a component (`%s`) while rendering a " + @@ -19337,7 +19887,7 @@ function warnIfUnmockedScheduler(fiber) { didWarnAboutUnmockedScheduler === false && Scheduler.unstable_flushAllWithoutAsserting === undefined ) { - if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { + if (fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; error( @@ -19351,144 +19901,6 @@ function warnIfUnmockedScheduler(fiber) { } } } -} - -function computeThreadID(root, lane) { - // Interaction threads are unique per root and expiration time. - // NOTE: Intentionally unsound cast. All that matters is that it's a number - // and it represents a batch of work. Could make a helper function instead, - // but meh this is fine for now. - return lane * 1000 + root.interactionThreadID; -} - -function markSpawnedWork(lane) { - if (spawnedWorkDuringRender === null) { - spawnedWorkDuringRender = [lane]; - } else { - spawnedWorkDuringRender.push(lane); - } -} - -function scheduleInteractions(root, lane, interactions) { - if (interactions.size > 0) { - var pendingInteractionMap = root.pendingInteractionMap; - var pendingInteractions = pendingInteractionMap.get(lane); - - 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(lane, 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, lane); - subscriber.onWorkScheduled(interactions, threadID); - } - } -} - -function schedulePendingInteractions(root, lane) { - scheduleInteractions(root, lane, tracing.__interactionsRef.current); -} - -function startWorkOnPendingInteractions(root, lanes) { - // 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, - scheduledLane - ) { - if (includesSomeLane(lanes, scheduledLane)) { - 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 performConcurrentWorkOnRoot() - // 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, lanes); - - try { - subscriber.onWorkStarted(interactions, threadID); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { - throw error; - }); - } - } - } -} - -function finishPendingInteractions(root, committedLanes) { - var remainingLanesAfterCommit = root.pendingLanes; - var subscriber; - - try { - subscriber = tracing.__subscriberRef.current; - - if (subscriber !== null && root.memoizedInteractions.size > 0) { - // FIXME: More than one lane can finish in a single commit. - var threadID = computeThreadID(root, committedLanes); - subscriber.onWorkStopped(root.memoizedInteractions, threadID); - } - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, 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, lane) { - // 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 (!includesSomeLane(remainingLanesAfterCommit, lane)) { - pendingInteractionMap.delete(lane); - 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$1, function() { - throw error; - }); - } - } - }); - } - }); - } } // `act` testing API function shouldForceFlushFallbacksInDEV() { @@ -19499,11 +19911,6 @@ function shouldForceFlushFallbacksInDEV() { var actingUpdatesScopeDepth = 0; -function detachFiberAfterEffects(fiber) { - fiber.sibling = null; - fiber.stateNode = null; -} - var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. var failedBoundaries = null; @@ -19980,9 +20387,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.mode = mode; // Effects this.flags = NoFlags; - this.nextEffect = null; - this.firstEffect = null; - this.lastEffect = null; + this.subtreeFlags = NoFlags; + this.deletions = null; this.lanes = NoLanes; this.childLanes = NoLanes; this.alternate = null; @@ -20109,11 +20515,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.type = current.type; // We already have an alternate. // Reset the effect tag. - workInProgress.flags = NoFlags; // The effect list is no longer valid. + workInProgress.flags = NoFlags; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; { // We intentionally reset, rather than copy, actualDuration & actualStartTime. @@ -20123,8 +20528,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; } - } + } // Reset all effects except static ones. + // Static effects are not specific to a render. + workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -20181,13 +20588,10 @@ function resetWorkInProgress(workInProgress, renderLanes) { // when they should be reading from current and writing to workInProgress. // We assume pendingProps, index, key, ref, return are still untouched to // avoid doing another reconciliation. - // Reset the effect tag but keep any Placement tags, since that's something + // Reset the effect flags but keep any Placement tags, since that's something // that child fiber is setting, not the reconciliation. - workInProgress.flags &= Placement; // The effect list is no longer valid. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; var current = workInProgress.alternate; if (current === null) { @@ -20195,6 +20599,7 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = NoLanes; workInProgress.lanes = renderLanes; workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags; workInProgress.memoizedProps = null; workInProgress.memoizedState = null; workInProgress.updateQueue = null; @@ -20212,6 +20617,8 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. @@ -20238,13 +20645,19 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag) { +function createHostRootFiber( + tag, + isStrictMode, + concurrentUpdatesByDefaultOverride +) { var mode; if (tag === ConcurrentRoot) { - mode = ConcurrentMode | BlockingMode | StrictMode; - } else if (tag === BlockingRoot) { - mode = BlockingMode | StrictMode; + mode = ConcurrentMode; + + if (isStrictMode === true) { + mode |= StrictLegacyMode; + } } else { mode = NoMode; } @@ -20296,7 +20709,7 @@ function createFiberFromTypeAndProps( case REACT_STRICT_MODE_TYPE: fiberTag = Mode; - mode |= StrictMode; + mode |= StrictLegacyMode | StrictEffectsMode; break; case REACT_PROFILER_TYPE: @@ -20318,6 +20731,10 @@ function createFiberFromTypeAndProps( // eslint-disable-next-line no-fallthrough + case REACT_CACHE_TYPE: + + // eslint-disable-next-line no-fallthrough + default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -20365,7 +20782,7 @@ function createFiberFromTypeAndProps( "named imports."; } - var ownerName = owner ? getComponentName(owner.type) : null; + var ownerName = owner ? getComponentNameFromFiber(owner) : null; if (ownerName) { info += "\n\nCheck the render method of `" + ownerName + "`."; @@ -20430,14 +20847,15 @@ function createFiberFromFragment(elements, mode, lanes, key) { function createFiberFromProfiler(pendingProps, mode, lanes, key) { { if (typeof pendingProps.id !== "string") { - error('Profiler must specify an "id" as a prop'); + error( + 'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', + typeof pendingProps.id + ); } } - var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag. - + var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); fiber.elementType = REACT_PROFILER_TYPE; - fiber.type = REACT_PROFILER_TYPE; fiber.lanes = lanes; { @@ -20451,51 +20869,25 @@ function createFiberFromProfiler(pendingProps, mode, lanes, key) { } function createFiberFromSuspense(pendingProps, mode, lanes, key) { - var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // 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; + var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); fiber.elementType = REACT_SUSPENSE_TYPE; fiber.lanes = lanes; return fiber; } function createFiberFromSuspenseList(pendingProps, mode, lanes, 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.lanes = lanes; return fiber; } function createFiberFromOffscreen(pendingProps, mode, lanes, key) { - var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); // TODO: The OffscreenComponent 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_OFFSCREEN_TYPE; - } - + var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); fiber.elementType = REACT_OFFSCREEN_TYPE; fiber.lanes = lanes; return fiber; } function createFiberFromLegacyHidden(pendingProps, mode, lanes, key) { - var fiber = createFiber(LegacyHiddenComponent, pendingProps, key, mode); // TODO: The LegacyHidden 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_LEGACY_HIDDEN_TYPE; - } - + var fiber = createFiber(LegacyHiddenComponent, pendingProps, key, mode); fiber.elementType = REACT_LEGACY_HIDDEN_TYPE; fiber.lanes = lanes; return fiber; @@ -20546,9 +20938,8 @@ function assignFiberPropertiesInDEV(target, source) { target.dependencies = source.dependencies; target.mode = source.mode; target.flags = source.flags; - target.nextEffect = source.nextEffect; - target.firstEffect = source.firstEffect; - target.lastEffect = source.lastEffect; + target.subtreeFlags = source.subtreeFlags; + target.deletions = source.deletions; target.lanes = source.lanes; target.childLanes = source.childLanes; target.alternate = source.alternate; @@ -20580,7 +20971,7 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.pendingContext = null; this.hydrate = hydrate; this.callbackNode = null; - this.callbackPriority = NoLanePriority; + this.callbackPriority = NoLane; this.eventTimes = createLaneMap(NoLanes); this.expirationTimes = createLaneMap(NoTimestamp); this.pendingLanes = NoLanes; @@ -20592,18 +20983,8 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.entangledLanes = NoLanes; this.entanglements = createLaneMap(NoLanes); - { - this.interactionThreadID = tracing.unstable_getThreadID(); - this.memoizedInteractions = new Set(); - this.pendingInteractionMap = new Map(); - } - { switch (tag) { - case BlockingRoot: - this._debugRootType = "createBlockingRoot()"; - break; - case ConcurrentRoot: this._debugRootType = "createRoot()"; break; @@ -20615,13 +20996,28 @@ function FiberRootNode(containerInfo, tag, hydrate) { } } -function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { +function createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride +) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag); + var uninitializedFiber = createHostRootFiber(tag, isStrictMode); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + + { + var _initialState = { + element: null + }; + uninitializedFiber.memoizedState = _initialState; + } + initializeUpdateQueue(uninitializedFiber); return root; } @@ -20695,8 +21091,8 @@ function findHostInstanceWithWarning(component, methodName) { return null; } - if (hostFiber.mode & StrictMode) { - var componentName = getComponentName(fiber.type) || "Component"; + if (hostFiber.mode & StrictLegacyMode) { + var componentName = getComponentNameFromFiber(fiber) || "Component"; if (!didWarnAboutFindNodeInStrictMode[componentName]) { didWarnAboutFindNodeInStrictMode[componentName] = true; @@ -20705,7 +21101,7 @@ function findHostInstanceWithWarning(component, methodName) { try { setCurrentFiber(hostFiber); - if (fiber.mode & StrictMode) { + if (fiber.mode & StrictLegacyMode) { error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + @@ -20744,8 +21140,21 @@ function findHostInstanceWithWarning(component, methodName) { } } -function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); +function createContainer( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride +) { + return createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + isStrictMode + ); } function updateContainer(element, container, parentComponent, callback) { { @@ -20781,7 +21190,7 @@ function updateContainer(element, container, parentComponent, callback) { "triggering nested component updates from render is not allowed. " + "If necessary, trigger nested updates in componentDidUpdate.\n\n" + "Check the render method of %s.", - getComponentName(current.type) || "Unknown" + getComponentNameFromFiber(current) || "Unknown" ); } } @@ -20809,7 +21218,12 @@ function updateContainer(element, container, parentComponent, callback) { } enqueueUpdate(current$1, update); - scheduleUpdateOnFiber(current$1, lane, eventTime); + var root = scheduleUpdateOnFiber(current$1, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, current$1, lane); + } + return lane; } function getPublicRootInstance(container) { @@ -20847,10 +21261,10 @@ var setSuspenseHandler = null; { var copyWithDeleteImpl = function(obj, path, index) { var key = path[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); if (index + 1 === path.length) { - if (Array.isArray(updated)) { + if (isArray(updated)) { updated.splice(key, 1); } else { delete updated[key]; @@ -20869,14 +21283,14 @@ var setSuspenseHandler = null; var copyWithRenameImpl = function(obj, oldPath, newPath, index) { var oldKey = oldPath[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); if (index + 1 === oldPath.length) { var newKey = newPath[index]; // $FlowFixMe number or string is fine here updated[newKey] = updated[oldKey]; - if (Array.isArray(updated)) { + if (isArray(updated)) { updated.splice(oldKey, 1); } else { delete updated[oldKey]; @@ -20921,7 +21335,7 @@ var setSuspenseHandler = null; } var key = path[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); return updated; @@ -21078,7 +21492,10 @@ function injectIntoDevTools(devToolsConfig) { scheduleRoot: scheduleRoot, setRefreshHandler: setRefreshHandler, // Enables DevTools to append owner stacks to error messages in DEV mode. - getCurrentFiber: getCurrentFiberForDevTools + getCurrentFiber: getCurrentFiberForDevTools, + // Enables DevTools to detect reconciler version rather than renderer version + // which may not match for third party renderers. + reconcilerVersion: ReactVersion }); } @@ -21155,7 +21572,7 @@ var getInspectorDataForViewAtPoint; var createHierarchy = function(fiberHierarchy) { return fiberHierarchy.map(function(fiber) { return { - name: getComponentName(fiber.type), + name: getComponentNameFromType(fiber.type), getInspectorData: function(findNodeHandle) { return { props: getHostProps(fiber), @@ -21270,23 +21687,25 @@ var getInspectorDataForViewAtPoint; } closestInstance = - internalInstanceHandle.stateNode.canonical._internalInstanceHandle; + internalInstanceHandle.stateNode.canonical._internalInstanceHandle; // Note: this is deprecated and we want to remove it ASAP. Keeping it here for React DevTools compatibility for now. + + var nativeViewTag = + internalInstanceHandle.stateNode.canonical._nativeTag; nativeFabricUIManager.measure( internalInstanceHandle.stateNode.node, function(x, y, width, height, pageX, pageY) { + var inspectorData = getInspectorDataForInstance(closestInstance); callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: pageX, - top: pageY, - width: width, - height: height - } + Object.assign({}, inspectorData, { + pointerY: locationY, + frame: { + left: pageX, + top: pageY, + width: width, + height: height }, - getInspectorDataForInstance(closestInstance) - ) + touchedViewTag: nativeViewTag + }) ); } ); @@ -21339,7 +21758,7 @@ function findHostInstance_DEPRECATED(componentOrHandle) { "never access something that requires stale data from the previous " + "render, such as refs. Move this logic to componentDidMount and " + "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" + getComponentNameFromType(owner.type) || "A component" ); } @@ -21349,13 +21768,15 @@ function findHostInstance_DEPRECATED(componentOrHandle) { if (componentOrHandle == null) { return null; - } + } // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN if (componentOrHandle._nativeTag) { + // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN return componentOrHandle; - } + } // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) { + // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN return componentOrHandle.canonical; } @@ -21375,7 +21796,7 @@ function findHostInstance_DEPRECATED(componentOrHandle) { if (hostInstance.canonical) { // Fabric return hostInstance.canonical; - } + } // $FlowFixMe[incompatible-return] return hostInstance; } @@ -21392,7 +21813,7 @@ function findNodeHandle(componentOrHandle) { "never access something that requires stale data from the previous " + "render, such as refs. Move this logic to componentDidMount and " + "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" + getComponentNameFromType(owner.type) || "A component" ); } @@ -21466,17 +21887,49 @@ function dispatchCommand(handle, command, args) { } } -function render(element, containerTag, callback) { +function sendAccessibilityEvent(handle, eventType) { + if (handle._nativeTag == null) { + { + error( + "sendAccessibilityEvent was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ); + } + + return; + } + + if (handle._internalInstanceHandle) { + nativeFabricUIManager.sendAccessibilityEvent( + handle._internalInstanceHandle.stateNode.node, + eventType + ); + } else { + ReactNativePrivateInterface.legacySendAccessibilityEvent( + handle._nativeTag, + eventType + ); + } +} + +function render(element, containerTag, callback, concurrentRoot) { 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, LegacyRoot, false); + root = createContainer( + containerTag, + concurrentRoot ? ConcurrentRoot : LegacyRoot, + false, + null, + false + ); roots.set(containerTag, root); } - updateContainer(element, root, null, callback); + updateContainer(element, root, null, callback); // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN + return getPublicRootInstance(root); } @@ -21522,6 +21975,7 @@ exports.dispatchCommand = dispatchCommand; exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; exports.findNodeHandle = findNodeHandle; exports.render = render; +exports.sendAccessibilityEvent = sendAccessibilityEvent; exports.stopSurface = stopSurface; exports.unmountComponentAtNode = unmountComponentAtNode; diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 9f53caacdd48fa..7d8cdbe0a52632 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ "use strict"; @@ -62,7 +62,8 @@ function invokeGuardedCallbackAndCatchFirstError( hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } } -var getFiberCurrentPropsFromNode = null, +var isArrayImpl = Array.isArray, + getFiberCurrentPropsFromNode = null, getInstanceFromNode = null, getNodeFromInstance = null; function executeDispatch(event, listener, inst) { @@ -74,7 +75,7 @@ function executeDispatch(event, listener, inst) { function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; - if (Array.isArray(dispatchListener)) + if (isArrayImpl(dispatchListener)) throw Error("executeDirectDispatch(...): Invalid `event`."); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) @@ -335,9 +336,9 @@ function accumulate(current, next) { ); return null == current ? next - : Array.isArray(current) + : isArrayImpl(current) ? current.concat(next) - : Array.isArray(next) + : isArrayImpl(next) ? [current].concat(next) : [current, next]; } @@ -347,12 +348,12 @@ function accumulateInto(current, next) { "accumulateInto(...): Accumulated items must not be null or undefined." ); if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; + if (isArrayImpl(current)) { + if (isArrayImpl(next)) return current.push.apply(current, next), current; current.push(next); return current; } - return Array.isArray(next) ? [current].concat(next) : [current, next]; + return isArrayImpl(next) ? [current].concat(next) : [current, next]; } function forEachAccumulated(arr, cb, scope) { Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); @@ -578,7 +579,7 @@ var ResponderEventPlugin = { b: { JSCompiler_temp = shouldSetEventType._dispatchListeners; targetInst = shouldSetEventType._dispatchInstances; - if (Array.isArray(JSCompiler_temp)) + if (isArrayImpl(JSCompiler_temp)) for ( depthA = 0; depthA < JSCompiler_temp.length && @@ -929,7 +930,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_214 = { +var injectedNamesToPlugins$jscomp$inline_216 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -964,34 +965,34 @@ var injectedNamesToPlugins$jscomp$inline_214 = { } } }, - isOrderingDirty$jscomp$inline_215 = !1, - pluginName$jscomp$inline_216; -for (pluginName$jscomp$inline_216 in injectedNamesToPlugins$jscomp$inline_214) + isOrderingDirty$jscomp$inline_217 = !1, + pluginName$jscomp$inline_218; +for (pluginName$jscomp$inline_218 in injectedNamesToPlugins$jscomp$inline_216) if ( - injectedNamesToPlugins$jscomp$inline_214.hasOwnProperty( - pluginName$jscomp$inline_216 + injectedNamesToPlugins$jscomp$inline_216.hasOwnProperty( + pluginName$jscomp$inline_218 ) ) { - var pluginModule$jscomp$inline_217 = - injectedNamesToPlugins$jscomp$inline_214[pluginName$jscomp$inline_216]; + var pluginModule$jscomp$inline_219 = + injectedNamesToPlugins$jscomp$inline_216[pluginName$jscomp$inline_218]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_216) || - namesToPlugins[pluginName$jscomp$inline_216] !== - pluginModule$jscomp$inline_217 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_218) || + namesToPlugins[pluginName$jscomp$inline_218] !== + pluginModule$jscomp$inline_219 ) { - if (namesToPlugins[pluginName$jscomp$inline_216]) + if (namesToPlugins[pluginName$jscomp$inline_218]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_216 + + pluginName$jscomp$inline_218 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_216 - ] = pluginModule$jscomp$inline_217; - isOrderingDirty$jscomp$inline_215 = !0; + pluginName$jscomp$inline_218 + ] = pluginModule$jscomp$inline_219; + isOrderingDirty$jscomp$inline_217 = !0; } } -isOrderingDirty$jscomp$inline_215 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_217 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -1006,13 +1007,27 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - (from || to).stateNode.canonical._internalInstanceHandle || - (null !== to - ? ReactNativePrivateInterface.UIManager.setJSResponder( - to.stateNode.canonical._nativeTag, - blockNativeResponder - ) - : ReactNativePrivateInterface.UIManager.clearJSResponder()); + var fromOrTo = from || to; + (fromOrTo = fromOrTo && fromOrTo.stateNode) && + fromOrTo.canonical._internalInstanceHandle + ? (from && + nativeFabricUIManager.setIsJSResponder( + from.stateNode.node, + !1, + blockNativeResponder || !1 + ), + to && + nativeFabricUIManager.setIsJSResponder( + to.stateNode.node, + !0, + blockNativeResponder || !1 + )) + : null !== to + ? ReactNativePrivateInterface.UIManager.setJSResponder( + to.stateNode.canonical._nativeTag, + blockNativeResponder + ) + : ReactNativePrivateInterface.UIManager.clearJSResponder(); } }); var ReactSharedInternals = @@ -1089,13 +1104,18 @@ function getComponentNameFromType(type) { return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; - innerType = innerType.displayName || innerType.name || ""; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: return ( - type.displayName || - ("" !== innerType ? "ForwardRef(" + innerType + ")" : "ForwardRef") + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" ); - case REACT_MEMO_TYPE: - return getComponentNameFromType(type.type); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; @@ -1307,7 +1327,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) + if (isArrayImpl(node)) for (var i = node.length; i-- && 0 < removedKeyCount; ) restoreDeletedValuesInNestedArray( updatePayload, @@ -1353,9 +1373,9 @@ function diffNestedProperty( : prevProp ? clearNestedProperty(updatePayload, prevProp, validAttributes) : updatePayload; - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) + if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { var minLength = prevProp.length < nextProp.length ? prevProp.length : nextProp.length, i; @@ -1380,7 +1400,7 @@ function diffNestedProperty( ); return updatePayload; } - return Array.isArray(prevProp) + return isArrayImpl(prevProp) ? diffProperties( updatePayload, ReactNativePrivateInterface.flattenStyle(prevProp), @@ -1396,7 +1416,7 @@ function diffNestedProperty( } function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) return updatePayload; - if (!Array.isArray(nextProp)) + if (!isArrayImpl(nextProp)) return diffProperties( updatePayload, emptyObject, @@ -1413,7 +1433,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { } function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) return updatePayload; - if (!Array.isArray(prevProp)) + if (!isArrayImpl(prevProp)) return diffProperties( updatePayload, prevProp, @@ -1531,7 +1551,7 @@ function executeDispatchesAndReleaseTopLevel(e) { if (e) { var dispatchListeners = e._dispatchListeners, dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) + if (isArrayImpl(dispatchListeners)) for ( var i = 0; i < dispatchListeners.length && !e.isPropagationStopped(); @@ -1591,6 +1611,28 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } +var scheduleCallback = Scheduler.unstable_scheduleCallback, + cancelCallback = Scheduler.unstable_cancelCallback, + shouldYield = Scheduler.unstable_shouldYield, + requestPaint = Scheduler.unstable_requestPaint, + now = Scheduler.unstable_now, + ImmediatePriority = Scheduler.unstable_ImmediatePriority, + UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + NormalPriority = Scheduler.unstable_NormalPriority, + IdlePriority = Scheduler.unstable_IdlePriority, + rendererID = null, + injectedHook = null; +function onCommitRoot(root) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + root, + void 0, + 128 === (root.current.flags & 128) + ); + } catch (err) {} +} var nextTransitionLane = 64, nextRetryLane = 4194304; function getHighestPriorityLanes(lanes) { @@ -1649,18 +1691,19 @@ function getNextLanes(root, wipLanes) { suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes, nonIdlePendingLanes = pendingLanes & 268435455; - 0 !== nonIdlePendingLanes - ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes), - 0 !== pendingLanes - ? (nextLanes = getHighestPriorityLanes(pendingLanes)) - : ((pingedLanes &= nonIdlePendingLanes), - 0 !== pingedLanes && - (nextLanes = getHighestPriorityLanes(pingedLanes)))) - : ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + if (0 !== nonIdlePendingLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? (nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes))); + } else + (nonIdlePendingLanes = pendingLanes & ~suspendedLanes), 0 !== nonIdlePendingLanes ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) : 0 !== pingedLanes && - (nextLanes = getHighestPriorityLanes(pingedLanes))); + (nextLanes = getHighestPriorityLanes(pingedLanes)); if (0 === nextLanes) return 0; if ( 0 !== wipLanes && @@ -1672,13 +1715,16 @@ function getNextLanes(root, wipLanes) { (16 === suspendedLanes && 0 !== (pingedLanes & 4194240))) ) return wipLanes; + 0 === (root.current.mode & 32) && + 0 !== (nextLanes & 4) && + (nextLanes |= pendingLanes & 16); wipLanes = root.entangledLanes; if (0 !== wipLanes) for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (suspendedLanes = 31 - clz32(wipLanes)), - (pingedLanes = 1 << suspendedLanes), - (nextLanes |= root[suspendedLanes]), - (wipLanes &= ~pingedLanes); + (pendingLanes = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~suspendedLanes); return nextLanes; } function computeExpirationTime(lane, currentTime) { @@ -1706,12 +1752,13 @@ function computeExpirationTime(lane, currentTime) { case 524288: case 1048576: case 2097152: + return currentTime + 5e3; case 4194304: case 8388608: case 16777216: case 33554432: case 67108864: - return currentTime + 5e3; + return -1; case 134217728: case 268435456: case 536870912: @@ -1737,16 +1784,12 @@ function markRootUpdated(root, updateLane, eventTime) { updateLane = 31 - clz32(updateLane); root[updateLane] = eventTime; } -function markRootExpired(root, expiredLanes) { - root.entanglements[0] |= expiredLanes; - root.entangledLanes |= 1; - root.pendingLanes |= 1; -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; root.suspendedLanes = 0; root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; root.mutableReadLanes &= remainingLanes; root.entangledLanes &= remainingLanes; remainingLanes = root.entanglements; @@ -1905,7 +1948,8 @@ function describeFunctionComponentFrame(fn, source) { ? describeComponentFrame(fn.displayName || fn.name || null, source, null) : ""; } -var valueStack = [], +var hasOwnProperty = Object.prototype.hasOwnProperty, + valueStack = [], index = -1; function createCursor(defaultValue) { return { current: defaultValue }; @@ -2001,31 +2045,10 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor); push(didPerformWorkStackCursor, didChange); } -var scheduleCallback = Scheduler.unstable_scheduleCallback, - cancelCallback = Scheduler.unstable_cancelCallback, - shouldYield = Scheduler.unstable_shouldYield, - requestPaint = Scheduler.unstable_requestPaint, - now = Scheduler.unstable_now, - ImmediatePriority = Scheduler.unstable_ImmediatePriority, - UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority = Scheduler.unstable_NormalPriority, - IdlePriority = Scheduler.unstable_IdlePriority, - rendererID = null, - injectedHook = null; -function onCommitRoot(root) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - root, - void 0, - 128 === (root.current.flags & 128) - ); - } catch (err) {} -} var syncQueue = null, + includesLegacySyncCallbacks = !1, isFlushingSyncQueue = !1; -function flushSyncCallbackQueue() { +function flushSyncCallbacks() { if (!isFlushingSyncQueue && null !== syncQueue) { isFlushingSyncQueue = !0; var i = 0, @@ -2038,9 +2061,10 @@ function flushSyncCallbackQueue() { while (null !== callback); } syncQueue = null; + includesLegacySyncCallbacks = !1; } catch (error) { throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), error); } finally { (currentUpdatePriority = previousUpdatePriority), @@ -2053,8 +2077,7 @@ var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, - hasOwnProperty = Object.prototype.hasOwnProperty; +var objectIs = "function" === typeof Object.is ? Object.is : is; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2353,6 +2376,7 @@ function processUpdateQueue( } } null !== pendingQueue.callback && + 0 !== pendingQueue.lane && ((workInProgress$jscomp$0.flags |= 64), (updateLane = queue.effects), null === updateLane @@ -2547,7 +2571,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && @@ -2569,7 +2592,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var isArray = Array.isArray; function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2622,15 +2644,14 @@ function coerceRef(returnFiber, current, element) { return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if ("textarea" !== returnFiber.type) - throw ((returnFiber = Object.prototype.toString.call(newChild)), - Error( - "Objects are not valid as a React child (found: " + - ("[object Object]" === returnFiber - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : returnFiber) + - "). If you meant to render a collection of children, use an array instead." - )); + returnFiber = Object.prototype.toString.call(newChild); + throw Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === returnFiber + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : returnFiber) + + "). If you meant to render a collection of children, use an array instead." + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { @@ -2792,7 +2813,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (newChild = createFiberFromFragment( newChild, @@ -2824,7 +2845,7 @@ function ChildReconciler(shouldTrackSideEffects) { ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key ? null : updateFragment(returnFiber, oldFiber, newChild, lanes, null); @@ -2863,7 +2884,7 @@ function ChildReconciler(shouldTrackSideEffects) { updatePortal(returnFiber, existingChildren, newChild, lanes) ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (existingChildren = existingChildren.get(newIdx) || null), updateFragment(returnFiber, existingChildren, newChild, lanes, null) @@ -3046,20 +3067,19 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.type === REACT_FRAGMENT_TYPE && null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); - var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) + if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; + var key = newChild.key; for ( isUnkeyedTopLevelFragment = currentFirstChild; null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - isObject = newChild.type; - if (isObject === REACT_FRAGMENT_TYPE) { + if (isUnkeyedTopLevelFragment.key === key) { + key = newChild.type; + if (key === REACT_FRAGMENT_TYPE) { if (7 === isUnkeyedTopLevelFragment.tag) { deleteRemainingChildren( returnFiber, @@ -3073,7 +3093,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; break a; } - } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + } else if (isUnkeyedTopLevelFragment.elementType === key) { deleteRemainingChildren( returnFiber, isUnkeyedTopLevelFragment.sibling @@ -3165,6 +3185,22 @@ function ChildReconciler(shouldTrackSideEffects) { } return placeSingleChild(returnFiber); } + if (isArrayImpl(newChild)) + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + if (getIteratorFn(newChild)) + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + throwOnInvalidObjectType(returnFiber, newChild); + } if ("string" === typeof newChild || "number" === typeof newChild) return ( (newChild = "" + newChild), @@ -3183,21 +3219,6 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); - if (isArray(newChild)) - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - if (getIteratorFn(newChild)) - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - isObject && throwOnInvalidObjectType(returnFiber, newChild); if ("undefined" === typeof newChild && !isUnkeyedTopLevelFragment) switch (returnFiber.tag) { case 1: @@ -3662,7 +3683,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(263168, 4, create, deps); + return mountEffectImpl(1049600, 4, create, deps); } function updateEffect(create, deps) { return updateEffectImpl(1024, 4, create, deps); @@ -3897,7 +3918,7 @@ var ContextOnlyDispatcher = { isPending = _mountState2[0]; _mountState2 = startTransition.bind(null, _mountState2[1]); mountWorkInProgressHook().memoizedState = _mountState2; - return [_mountState2, isPending]; + return [isPending, _mountState2]; }, useMutableSource: function(source, getSnapshot, subscribe) { var hook = mountWorkInProgressHook(); @@ -3946,8 +3967,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = updateReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -3988,8 +4010,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = rerenderReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4655,7 +4678,7 @@ function updateSuspenseFallbackChildren( (primaryChildren.pendingProps = primaryChildProps), (workInProgress.deletions = null)) : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 262144)); + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); null !== currentFallbackChildFragment ? (fallbackChildren = createWorkInProgress( currentFallbackChildFragment, @@ -5015,14 +5038,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$62 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$62 = lastTailNode), + for (var lastTailNode$64 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$62 + null === lastTailNode$64 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$62.sibling = null); + : (lastTailNode$64.sibling = null); } } function bubbleProperties(completedWork) { @@ -5032,19 +5055,19 @@ function bubbleProperties(completedWork) { newChildLanes = 0, subtreeFlags = 0; if (didBailout) - for (var child$63 = completedWork.child; null !== child$63; ) - (newChildLanes |= child$63.lanes | child$63.childLanes), - (subtreeFlags |= child$63.subtreeFlags & 262144), - (subtreeFlags |= child$63.flags & 262144), - (child$63.return = completedWork), - (child$63 = child$63.sibling); + for (var child$65 = completedWork.child; null !== child$65; ) + (newChildLanes |= child$65.lanes | child$65.childLanes), + (subtreeFlags |= child$65.subtreeFlags & 1835008), + (subtreeFlags |= child$65.flags & 1835008), + (child$65.return = completedWork), + (child$65 = child$65.sibling); else - for (child$63 = completedWork.child; null !== child$63; ) - (newChildLanes |= child$63.lanes | child$63.childLanes), - (subtreeFlags |= child$63.subtreeFlags), - (subtreeFlags |= child$63.flags), - (child$63.return = completedWork), - (child$63 = child$63.sibling); + for (child$65 = completedWork.child; null !== child$65; ) + (newChildLanes |= child$65.lanes | child$65.childLanes), + (subtreeFlags |= child$65.subtreeFlags), + (subtreeFlags |= child$65.flags), + (child$65.return = completedWork), + (child$65 = child$65.sibling); completedWork.subtreeFlags |= subtreeFlags; completedWork.childLanes = newChildLanes; return didBailout; @@ -5241,7 +5264,7 @@ function completeWork(current, workInProgress, renderLanes) { for (newProps = workInProgress.child; null !== newProps; ) (renderLanes = newProps), (type = current), - (renderLanes.flags &= 262146), + (renderLanes.flags &= 1835010), (updatePayload = renderLanes.alternate), null === updatePayload ? ((renderLanes.childLanes = 0), @@ -5615,8 +5638,8 @@ function commitHookEffectListMount(tag, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & tag) === tag) { - var create$80 = effect.create; - effect.destroy = create$80(); + var create$82 = effect.create; + effect.destroy = create$82(); } effect = effect.next; } while (effect !== finishedWork); @@ -5868,8 +5891,8 @@ function commitLayoutEffects(finishedWork) { commitUpdateQueue(firstChild, updateQueue, instance); break; case 3: - var updateQueue$81 = firstChild.updateQueue; - if (null !== updateQueue$81) { + var updateQueue$83 = firstChild.updateQueue; + if (null !== updateQueue$83) { current = null; if (null !== firstChild.child) switch (firstChild.child.tag) { @@ -5879,7 +5902,7 @@ function commitLayoutEffects(finishedWork) { case 1: current = firstChild.child.stateNode; } - commitUpdateQueue(firstChild, updateQueue$81, current); + commitUpdateQueue(firstChild, updateQueue$83, current); } break; case 5: @@ -5942,6 +5965,7 @@ function commitLayoutEffects(finishedWork) { var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -6007,7 +6031,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { 0 === executionContext && 0 === (fiber.mode & 1) && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue())) + includesLegacySyncCallbacks && flushSyncCallbacks())) : ensureRootIsScheduled(root, eventTime); return root; } @@ -6030,8 +6054,7 @@ function ensureRootIsScheduled(root, currentTime) { suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes, expirationTimes = root.expirationTimes, - lanes = root.pendingLanes, - expiredLanes = 0; + lanes = root.pendingLanes; 0 < lanes; ) { @@ -6041,10 +6064,9 @@ function ensureRootIsScheduled(root, currentTime) { if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) expirationTimes[index$5] = computeExpirationTime(lane, currentTime); - } else expirationTime <= currentTime && (expiredLanes |= lane); + } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } - 0 !== expiredLanes && markRootExpired(root, expiredLanes); suspendedLanes = getNextLanes( root, root === workInProgressRoot ? workInProgressRootRenderLanes : 0 @@ -6059,11 +6081,17 @@ function ensureRootIsScheduled(root, currentTime) { ) { null != existingCallbackNode && cancelCallback(existingCallbackNode); if (1 === currentTime) - (existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? (syncQueue = [existingCallbackNode]) - : syncQueue.push(existingCallbackNode), - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue), + 0 === root.tag + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + (includesLegacySyncCallbacks = !0), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)) + : ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), (existingCallbackNode = null); else { switch (lanesToEventPriority(suspendedLanes)) { @@ -6104,42 +6132,48 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - if (didTimeout) - return ( - markRootExpired(root, lanes), ensureRootIsScheduled(root, now()), null - ); - didTimeout = lanes; - var prevExecutionContext = executionContext; - executionContext |= 8; - var prevDispatcher = pushDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== didTimeout - ) - (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, didTimeout); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = prevExecutionContext; - null !== workInProgress - ? (didTimeout = 0) - : ((workInProgressRoot = null), - (workInProgressRootRenderLanes = 0), - (didTimeout = workInProgressRootExitStatus)); + var JSCompiler_inline_result = + 0 !== (lanes & root.expiredLanes) + ? !1 + : 0 !== (root.current.mode & 32) + ? !0 + : 0 === (lanes & 30); + if (JSCompiler_inline_result && !didTimeout) { + didTimeout = lanes; + JSCompiler_inline_result = executionContext; + executionContext |= 8; + var prevDispatcher = pushDispatcher(); + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== didTimeout + ) + (workInProgressRootRenderTargetTime = now() + 500), + prepareFreshStack(root, didTimeout); + do + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + ReactCurrentDispatcher$2.current = prevDispatcher; + executionContext = JSCompiler_inline_result; + null !== workInProgress + ? (didTimeout = 0) + : ((workInProgressRoot = null), + (workInProgressRootRenderLanes = 0), + (didTimeout = workInProgressRootExitStatus)); + } else didTimeout = renderRootSync(root, lanes); if (0 !== didTimeout) { 2 === didTimeout && ((executionContext |= 32), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + (JSCompiler_inline_result = getLanesToRetrySynchronouslyOnError(root)), + 0 !== JSCompiler_inline_result && + ((lanes = JSCompiler_inline_result), + (didTimeout = renderRootSync(root, JSCompiler_inline_result)))); if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6163,10 +6197,10 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; - prevExecutionContext = root.suspendedLanes; - if ((prevExecutionContext & lanes) !== lanes) { + JSCompiler_inline_result = root.suspendedLanes; + if ((JSCompiler_inline_result & lanes) !== lanes) { requestEventTime(); - root.pingedLanes |= root.suspendedLanes & prevExecutionContext; + root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result; break; } root.timeoutHandle = scheduleTimeout( @@ -6181,14 +6215,15 @@ function performConcurrentWorkOnRoot(root, didTimeout) { markRootSuspended$1(root, lanes); if ((lanes & 4194240) === lanes) break; didTimeout = root.eventTimes; - for (prevExecutionContext = -1; 0 < lanes; ) { + for (JSCompiler_inline_result = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); prevDispatcher = 1 << index$4; index$4 = didTimeout[index$4]; - index$4 > prevExecutionContext && (prevExecutionContext = index$4); + index$4 > JSCompiler_inline_result && + (JSCompiler_inline_result = index$4); lanes &= ~prevDispatcher; } - lanes = prevExecutionContext; + lanes = JSCompiler_inline_result; lanes = now() - lanes; lanes = (120 > lanes @@ -6241,17 +6276,16 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 24)) throw Error("Should not already be working."); flushPassiveEffects(); - var lanes; - if ((lanes = root === workInProgressRoot)) - lanes = 0 !== (root.entanglements[0] & workInProgressRootRenderLanes); - lanes = lanes ? workInProgressRootRenderLanes : getNextLanes(root, 0); + var lanes = getNextLanes(root, 0); + if (0 === (lanes & 1)) return ensureRootIsScheduled(root, now()), null; var exitStatus = renderRootSync(root, lanes); - 0 !== root.tag && - 2 === exitStatus && - ((executionContext |= 32), - root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + if (0 !== root.tag && 2 === exitStatus) { + executionContext |= 32; + root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + 0 !== errorRetryLanes && + ((lanes = errorRetryLanes), (exitStatus = renderRootSync(root, lanes))); + } if (1 === exitStatus) throw ((exitStatus = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6393,15 +6427,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$75 = returnFiber; + workInProgress$77 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$75.tag)) { - var nextState = workInProgress$75.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { + var nextState = workInProgress$77.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$75.memoizedProps; + var props = workInProgress$77.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6413,17 +6447,17 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$75.updateQueue; + var wakeables = workInProgress$77.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$75.updateQueue = updateQueue; + workInProgress$77.updateQueue = updateQueue; } else wakeables.add(wakeable); if ( - 0 === (workInProgress$75.mode & 1) && - workInProgress$75 !== returnFiber + 0 === (workInProgress$77.mode & 1) && + workInProgress$77 !== returnFiber ) { - workInProgress$75.flags |= 128; + workInProgress$77.flags |= 128; sourceFiber.flags |= 32768; sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) @@ -6456,12 +6490,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$75.flags |= 16384; - workInProgress$75.lanes = thrownValue; + workInProgress$77.flags |= 16384; + workInProgress$77.lanes = thrownValue; break a; } - workInProgress$75 = workInProgress$75.return; - } while (null !== workInProgress$75); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); value = Error( (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6470,47 +6504,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$75 = returnFiber; + workInProgress$77 = returnFiber; do { - switch (workInProgress$75.tag) { + switch (workInProgress$77.tag) { case 3: root = value; - workInProgress$75.flags |= 16384; + workInProgress$77.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$75.lanes |= thrownValue; - var update$76 = createRootErrorUpdate( - workInProgress$75, + workInProgress$77.lanes |= thrownValue; + var update$78 = createRootErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$75, update$76); + enqueueCapturedUpdate(workInProgress$77, update$78); break a; case 1: root = value; - var ctor = workInProgress$75.type, - instance = workInProgress$75.stateNode; + var ctor = workInProgress$77.type, + instance = workInProgress$77.stateNode; if ( - 0 === (workInProgress$75.flags & 128) && + 0 === (workInProgress$77.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$75.flags |= 16384; + workInProgress$77.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$75.lanes |= thrownValue; - var update$79 = createClassErrorUpdate( - workInProgress$75, + workInProgress$77.lanes |= thrownValue; + var update$81 = createClassErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$75, update$79); + enqueueCapturedUpdate(workInProgress$77, update$81); break a; } } - workInProgress$75 = workInProgress$75.return; - } while (null !== workInProgress$75); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6601,12 +6635,15 @@ function completeUnitOfWork(unitOfWork) { 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } function commitRoot(root) { - var previousUpdateLanePriority = currentUpdatePriority; + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig$2.transition; try { - (currentUpdatePriority = 1), + (ReactCurrentBatchConfig$2.transition = 0), + (currentUpdatePriority = 1), commitRootImpl(root, previousUpdateLanePriority); } finally { - currentUpdatePriority = previousUpdateLanePriority; + (ReactCurrentBatchConfig$2.transition = prevTransition), + (currentUpdatePriority = previousUpdateLanePriority); } return null; } @@ -6641,7 +6678,9 @@ function commitRootImpl(root, renderPriorityLevel) { })); remainingLanes = 0 !== (finishedWork.flags & 8054); if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { - remainingLanes = currentUpdatePriority; + remainingLanes = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = currentUpdatePriority; currentUpdatePriority = 1; var prevExecutionContext = executionContext; executionContext |= 16; @@ -6652,7 +6691,8 @@ function commitRootImpl(root, renderPriorityLevel) { commitLayoutEffects(finishedWork, root, lanes); requestPaint(); executionContext = prevExecutionContext; - currentUpdatePriority = remainingLanes; + currentUpdatePriority = previousPriority; + ReactCurrentBatchConfig$2.transition = remainingLanes; } else root.current = finishedWork; rootDoesHavePassiveEffects && ((rootDoesHavePassiveEffects = !1), @@ -6673,26 +6713,31 @@ function commitRootImpl(root, renderPriorityLevel) { (firstUncaughtError = null), root); if (0 !== (executionContext & 4)) return null; - flushSyncCallbackQueue(); + 0 !== (pendingPassiveEffectsLanes & 1) && + 0 !== root.tag && + flushPassiveEffects(); + flushSyncCallbacks(); return null; } function flushPassiveEffects() { - if (0 !== pendingPassiveEffectsLanes) { - var b = lanesToEventPriority(pendingPassiveEffectsLanes), + if (null !== rootWithPendingPassiveEffects) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), + prevTransition = ReactCurrentBatchConfig$2.transition, previousPriority = currentUpdatePriority; try { - currentUpdatePriority = 16 < b ? 16 : b; + ReactCurrentBatchConfig$2.transition = 0; + currentUpdatePriority = 16 > renderPriority ? 16 : renderPriority; if (null === rootWithPendingPassiveEffects) var JSCompiler_inline_result = !1; else { - var root = rootWithPendingPassiveEffects; + renderPriority = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; pendingPassiveEffectsLanes = 0; if (0 !== (executionContext & 24)) throw Error("Cannot flush passive effects while already rendering."); - b = executionContext; + var prevExecutionContext = executionContext; executionContext |= 16; - for (nextEffect = root.current; null !== nextEffect; ) { + for (nextEffect = renderPriority.current; null !== nextEffect; ) { var fiber = nextEffect, child = fiber.child; if (0 !== (nextEffect.flags & 16)) { @@ -6767,7 +6812,7 @@ function flushPassiveEffects() { nextEffect = fiber.return; } } - var finishedWork = root.current; + var finishedWork = renderPriority.current; for (nextEffect = finishedWork; null !== nextEffect; ) { child = nextEffect; var firstChild = child.child; @@ -6800,13 +6845,21 @@ function flushPassiveEffects() { nextEffect = deletions.return; } } - executionContext = b; - flushSyncCallbackQueue(); + executionContext = prevExecutionContext; + flushSyncCallbacks(); + if ( + injectedHook && + "function" === typeof injectedHook.onPostCommitFiberRoot + ) + try { + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); + } catch (err) {} JSCompiler_inline_result = !0; } return JSCompiler_inline_result; } finally { - currentUpdatePriority = previousPriority; + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$2.transition = prevTransition); } } return !1; @@ -7025,14 +7078,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? nextValue.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; - "function" === typeof getDerivedStateFromProps && - applyDerivedStateFromProps( - workInProgress, - updateLanes, - getDerivedStateFromProps, - current - ); nextValue.updater = classComponentUpdater; workInProgress.stateNode = nextValue; nextValue._reactInternals = workInProgress; @@ -7247,11 +7292,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateLanes = workInProgress.type._context; nextValue = workInProgress.pendingProps; hasContext = workInProgress.memoizedProps; - getDerivedStateFromProps = nextValue.value; + var newValue = nextValue.value; push(valueCursor, updateLanes._currentValue2); - updateLanes._currentValue2 = getDerivedStateFromProps; + updateLanes._currentValue2 = newValue; if (null !== hasContext) - if (objectIs(hasContext.value, getDerivedStateFromProps)) { + if (objectIs(hasContext.value, newValue)) { if ( hasContext.children === nextValue.children && !didPerformWorkStackCursor.current @@ -7265,25 +7310,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - getDerivedStateFromProps = workInProgress.child, - null !== getDerivedStateFromProps && - (getDerivedStateFromProps.return = workInProgress); - null !== getDerivedStateFromProps; + newValue = workInProgress.child, + null !== newValue && (newValue.return = workInProgress); + null !== newValue; ) { - var list = getDerivedStateFromProps.dependencies; + var list = newValue.dependencies; if (null !== list) { - hasContext = getDerivedStateFromProps.child; + hasContext = newValue.child; for ( var dependency = list.firstContext; null !== dependency; ) { if (dependency.context === updateLanes) { - if (1 === getDerivedStateFromProps.tag) { + if (1 === newValue.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; - var updateQueue = getDerivedStateFromProps.updateQueue; + var updateQueue = newValue.updateQueue; if (null !== updateQueue) { updateQueue = updateQueue.shared; var pending = updateQueue.pending; @@ -7294,13 +7338,10 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateQueue.pending = dependency; } } - getDerivedStateFromProps.lanes |= renderLanes; - dependency = getDerivedStateFromProps.alternate; + newValue.lanes |= renderLanes; + dependency = newValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - getDerivedStateFromProps.return, - renderLanes - ); + scheduleWorkOnParentPath(newValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7308,32 +7349,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else hasContext = - 10 === getDerivedStateFromProps.tag - ? getDerivedStateFromProps.type === workInProgress.type + 10 === newValue.tag + ? newValue.type === workInProgress.type ? null - : getDerivedStateFromProps.child - : getDerivedStateFromProps.child; - if (null !== hasContext) - hasContext.return = getDerivedStateFromProps; + : newValue.child + : newValue.child; + if (null !== hasContext) hasContext.return = newValue; else - for ( - hasContext = getDerivedStateFromProps; - null !== hasContext; - - ) { + for (hasContext = newValue; null !== hasContext; ) { if (hasContext === workInProgress) { hasContext = null; break; } - getDerivedStateFromProps = hasContext.sibling; - if (null !== getDerivedStateFromProps) { - getDerivedStateFromProps.return = hasContext.return; - hasContext = getDerivedStateFromProps; + newValue = hasContext.sibling; + if (null !== newValue) { + newValue.return = hasContext.return; + hasContext = newValue; break; } hasContext = hasContext.return; } - getDerivedStateFromProps = hasContext; + newValue = hasContext; } reconcileChildren( current, @@ -7472,7 +7508,7 @@ function createWorkInProgress(current, pendingProps) { (workInProgress.flags = 0), (workInProgress.subtreeFlags = 0), (workInProgress.deletions = null)); - workInProgress.flags = current.flags & 262144; + workInProgress.flags = current.flags & 1835008; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7511,10 +7547,7 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - 1 <= - (null == pendingProps.unstable_level - ? 1 - : pendingProps.unstable_level) && (mode |= 8); + mode |= 24; break; case REACT_PROFILER_TYPE: return ( @@ -7620,7 +7653,7 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.callbackPriority = 0; this.eventTimes = createLaneMap(0); this.expirationTimes = createLaneMap(-1); - this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; + this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.expiredLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; this.entanglements = createLaneMap(0); } function createPortal(children, containerInfo, implementation) { @@ -7732,14 +7765,14 @@ batchedUpdatesImpl = function(fn, a) { (executionContext = prevExecutionContext), 0 === executionContext && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue()); + includesLegacySyncCallbacks && flushSyncCallbacks()); } }; var roots = new Map(), - devToolsConfig$jscomp$inline_940 = { + devToolsConfig$jscomp$inline_942 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.3", + version: "17.0.3-2d8d133e1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7754,11 +7787,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1171 = { - bundleType: devToolsConfig$jscomp$inline_940.bundleType, - version: devToolsConfig$jscomp$inline_940.version, - rendererPackageName: devToolsConfig$jscomp$inline_940.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_940.rendererConfig, +var internals$jscomp$inline_1180 = { + bundleType: devToolsConfig$jscomp$inline_942.bundleType, + version: devToolsConfig$jscomp$inline_942.version, + rendererPackageName: devToolsConfig$jscomp$inline_942.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_942.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7773,25 +7806,26 @@ var internals$jscomp$inline_1171 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_940.findFiberByHostInstance || + devToolsConfig$jscomp$inline_942.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, - getCurrentFiber: null + getCurrentFiber: null, + reconcilerVersion: "17.0.3-2d8d133e1" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1172 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1181 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1172.isDisabled && - hook$jscomp$inline_1172.supportsFiber + !hook$jscomp$inline_1181.isDisabled && + hook$jscomp$inline_1181.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1172.inject( - internals$jscomp$inline_1171 + (rendererID = hook$jscomp$inline_1181.inject( + internals$jscomp$inline_1180 )), - (injectedHook = hook$jscomp$inline_1172); + (injectedHook = hook$jscomp$inline_1181); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -7829,17 +7863,18 @@ exports.findHostInstance_DEPRECATED = function(componentOrHandle) { : componentOrHandle; }; exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { +exports.render = function(element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var JSCompiler_inline_result = createFiber(3, null, null, 0); - root.current = JSCompiler_inline_result; - JSCompiler_inline_result.stateNode = root; - JSCompiler_inline_result.memoizedState = { element: null }; - initializeUpdateQueue(JSCompiler_inline_result); - roots.set(containerTag, root); - } + root || + ((root = concurrentRoot ? 1 : 0), + (concurrentRoot = new FiberRootNode(containerTag, root, !1)), + (root = createFiber(3, null, null, 1 === root ? 1 : 0)), + (concurrentRoot.current = root), + (root.stateNode = concurrentRoot), + (root.memoizedState = { element: null }), + initializeUpdateQueue(root), + (root = concurrentRoot), + roots.set(containerTag, root)); updateContainer(element, root, null, callback); a: if (((element = root.current), element.child)) switch (element.child.tag) { diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.js b/Libraries/Renderer/implementations/ReactFabric-prod.js index 0ef34f37bb0d1d..ffd5e16d2974ce 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactFabric-prod * @preventMunge - * @generated + * @generated SignedSource<> */ "use strict"; @@ -63,7 +63,8 @@ function invokeGuardedCallbackAndCatchFirstError( hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } } -var getFiberCurrentPropsFromNode = null, +var isArrayImpl = Array.isArray, + getFiberCurrentPropsFromNode = null, getInstanceFromNode = null, getNodeFromInstance = null; function executeDispatch(event, listener, inst) { @@ -75,7 +76,7 @@ function executeDispatch(event, listener, inst) { function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; - if (Array.isArray(dispatchListener)) + if (isArrayImpl(dispatchListener)) throw Error("executeDirectDispatch(...): Invalid `event`."); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) @@ -289,36 +290,46 @@ function recordTouchEnd(touch) { (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } -var ResponderTouchHistoryStore = { - recordTouchTrack: function(topLevelType, nativeEvent) { - if (isMoveish(topLevelType)) - nativeEvent.changedTouches.forEach(recordTouchMove); - else if (isStartish(topLevelType)) - nativeEvent.changedTouches.forEach(recordTouchStart), - (touchHistory.numberActiveTouches = nativeEvent.touches.length), - 1 === touchHistory.numberActiveTouches && - (touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier); - else if ( - "topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType - ) - if ( - (nativeEvent.changedTouches.forEach(recordTouchEnd), - (touchHistory.numberActiveTouches = nativeEvent.touches.length), - 1 === touchHistory.numberActiveTouches) +var instrumentationCallback, + ResponderTouchHistoryStore = { + instrument: function(callback) { + instrumentationCallback = callback; + }, + recordTouchTrack: function(topLevelType, nativeEvent) { + null != instrumentationCallback && + instrumentationCallback(topLevelType, nativeEvent); + if (isMoveish(topLevelType)) + nativeEvent.changedTouches.forEach(recordTouchMove); + else if (isStartish(topLevelType)) + nativeEvent.changedTouches.forEach(recordTouchStart), + (touchHistory.numberActiveTouches = nativeEvent.touches.length), + 1 === touchHistory.numberActiveTouches && + (touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier); + else if ( + "topTouchEnd" === topLevelType || + "topTouchCancel" === topLevelType ) - for (topLevelType = 0; topLevelType < touchBank.length; topLevelType++) - if ( - ((nativeEvent = touchBank[topLevelType]), - null != nativeEvent && nativeEvent.touchActive) - ) { - touchHistory.indexOfSingleActiveTouch = topLevelType; - break; - } - }, - touchHistory: touchHistory -}; + if ( + (nativeEvent.changedTouches.forEach(recordTouchEnd), + (touchHistory.numberActiveTouches = nativeEvent.touches.length), + 1 === touchHistory.numberActiveTouches) + ) + for ( + topLevelType = 0; + topLevelType < touchBank.length; + topLevelType++ + ) + if ( + ((nativeEvent = touchBank[topLevelType]), + null != nativeEvent && nativeEvent.touchActive) + ) { + touchHistory.indexOfSingleActiveTouch = topLevelType; + break; + } + }, + touchHistory: touchHistory + }; function accumulate(current, next) { if (null == next) throw Error( @@ -326,9 +337,9 @@ function accumulate(current, next) { ); return null == current ? next - : Array.isArray(current) + : isArrayImpl(current) ? current.concat(next) - : Array.isArray(next) + : isArrayImpl(next) ? [current].concat(next) : [current, next]; } @@ -338,12 +349,12 @@ function accumulateInto(current, next) { "accumulateInto(...): Accumulated items must not be null or undefined." ); if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; + if (isArrayImpl(current)) { + if (isArrayImpl(next)) return current.push.apply(current, next), current; current.push(next); return current; } - return Array.isArray(next) ? [current].concat(next) : [current, next]; + return isArrayImpl(next) ? [current].concat(next) : [current, next]; } function forEachAccumulated(arr, cb, scope) { Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); @@ -569,7 +580,7 @@ var ResponderEventPlugin = { b: { JSCompiler_temp = shouldSetEventType._dispatchListeners; targetInst = shouldSetEventType._dispatchInstances; - if (Array.isArray(JSCompiler_temp)) + if (isArrayImpl(JSCompiler_temp)) for ( depthA = 0; depthA < JSCompiler_temp.length && @@ -920,7 +931,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_219 = { +var injectedNamesToPlugins$jscomp$inline_216 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -955,34 +966,34 @@ var injectedNamesToPlugins$jscomp$inline_219 = { } } }, - isOrderingDirty$jscomp$inline_220 = !1, - pluginName$jscomp$inline_221; -for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) + isOrderingDirty$jscomp$inline_217 = !1, + pluginName$jscomp$inline_218; +for (pluginName$jscomp$inline_218 in injectedNamesToPlugins$jscomp$inline_216) if ( - injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( - pluginName$jscomp$inline_221 + injectedNamesToPlugins$jscomp$inline_216.hasOwnProperty( + pluginName$jscomp$inline_218 ) ) { - var pluginModule$jscomp$inline_222 = - injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; + var pluginModule$jscomp$inline_219 = + injectedNamesToPlugins$jscomp$inline_216[pluginName$jscomp$inline_218]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || - namesToPlugins[pluginName$jscomp$inline_221] !== - pluginModule$jscomp$inline_222 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_218) || + namesToPlugins[pluginName$jscomp$inline_218] !== + pluginModule$jscomp$inline_219 ) { - if (namesToPlugins[pluginName$jscomp$inline_221]) + if (namesToPlugins[pluginName$jscomp$inline_218]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_221 + + pluginName$jscomp$inline_218 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_221 - ] = pluginModule$jscomp$inline_222; - isOrderingDirty$jscomp$inline_220 = !0; + pluginName$jscomp$inline_218 + ] = pluginModule$jscomp$inline_219; + isOrderingDirty$jscomp$inline_217 = !0; } } -isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_217 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -997,7 +1008,22 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - null !== to + var fromOrTo = from || to; + (fromOrTo = fromOrTo && fromOrTo.stateNode) && + fromOrTo.canonical._internalInstanceHandle + ? (from && + nativeFabricUIManager.setIsJSResponder( + from.stateNode.node, + !1, + blockNativeResponder || !1 + ), + to && + nativeFabricUIManager.setIsJSResponder( + to.stateNode.node, + !0, + blockNativeResponder || !1 + )) + : null !== to ? ReactNativePrivateInterface.UIManager.setJSResponder( to.stateNode.canonical._nativeTag, blockNativeResponder @@ -1021,7 +1047,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1040,6 +1067,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1049,7 +1077,7 @@ function getIteratorFn(maybeIterable) { maybeIterable["@@iterator"]; return "function" === typeof maybeIterable ? maybeIterable : null; } -function getComponentName(type) { +function getComponentNameFromType(type) { if (null == type) return null; if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; @@ -1066,6 +1094,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1075,22 +1105,83 @@ function getComponentName(type) { return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; - innerType = innerType.displayName || innerType.name || ""; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: return ( - type.displayName || - ("" !== innerType ? "ForwardRef(" + innerType + ")" : "ForwardRef") + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" ); - case REACT_MEMO_TYPE: - return getComponentName(type.type); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; try { - return getComponentName(type(innerType)); + return getComponentNameFromType(type(innerType)); } catch (x) {} } return null; } +function getComponentNameFromFiber(fiber) { + var type = fiber.type; + switch (fiber.tag) { + case 24: + return "Cache"; + case 9: + return (type.displayName || "Context") + ".Consumer"; + case 10: + return (type._context.displayName || "Context") + ".Provider"; + case 18: + return "DehydratedFragment"; + case 11: + return ( + (fiber = type.render), + (fiber = fiber.displayName || fiber.name || ""), + type.displayName || + ("" !== fiber ? "ForwardRef(" + fiber + ")" : "ForwardRef") + ); + case 7: + return "Fragment"; + case 5: + return type; + case 4: + return "Portal"; + case 3: + return "Root"; + case 6: + return "Text"; + case 16: + return getComponentNameFromType(type); + case 23: + return "LegacyHidden"; + case 8: + return type === REACT_STRICT_MODE_TYPE ? "StrictMode" : "Mode"; + case 22: + return "Offscreen"; + case 12: + return "Profiler"; + case 21: + return "Scope"; + case 13: + return "Suspense"; + case 19: + return "SuspenseList"; + case 1: + case 0: + case 17: + case 2: + case 14: + case 15: + if ("function" === typeof type) + return type.displayName || type.name || null; + if ("string" === typeof type) return type; + } + return null; +} function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1099,7 +1190,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1187,19 +1278,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1242,7 +1328,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) + if (isArrayImpl(node)) for (var i = node.length; i-- && 0 < removedKeyCount; ) restoreDeletedValuesInNestedArray( updatePayload, @@ -1288,9 +1374,9 @@ function diffNestedProperty( : prevProp ? clearNestedProperty(updatePayload, prevProp, validAttributes) : updatePayload; - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) + if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { var minLength = prevProp.length < nextProp.length ? prevProp.length : nextProp.length, i; @@ -1315,7 +1401,7 @@ function diffNestedProperty( ); return updatePayload; } - return Array.isArray(prevProp) + return isArrayImpl(prevProp) ? diffProperties( updatePayload, ReactNativePrivateInterface.flattenStyle(prevProp), @@ -1331,7 +1417,7 @@ function diffNestedProperty( } function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) return updatePayload; - if (!Array.isArray(nextProp)) + if (!isArrayImpl(nextProp)) return diffProperties( updatePayload, emptyObject, @@ -1348,7 +1434,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { } function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) return updatePayload; - if (!Array.isArray(prevProp)) + if (!isArrayImpl(prevProp)) return diffProperties( updatePayload, prevProp, @@ -1466,7 +1552,7 @@ function executeDispatchesAndReleaseTopLevel(e) { if (e) { var dispatchListeners = e._dispatchListeners, dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) + if (isArrayImpl(dispatchListeners)) for ( var i = 0; i < dispatchListeners.length && !e.isPropagationStopped(); @@ -1526,6 +1612,223 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } +var scheduleCallback = Scheduler.unstable_scheduleCallback, + cancelCallback = Scheduler.unstable_cancelCallback, + shouldYield = Scheduler.unstable_shouldYield, + requestPaint = Scheduler.unstable_requestPaint, + now = Scheduler.unstable_now, + ImmediatePriority = Scheduler.unstable_ImmediatePriority, + UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + NormalPriority = Scheduler.unstable_NormalPriority, + IdlePriority = Scheduler.unstable_IdlePriority, + rendererID = null, + injectedHook = null; +function onCommitRoot(root) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + root, + void 0, + 128 === (root.current.flags & 128) + ); + } catch (err) {} +} +var nextTransitionLane = 64, + nextRetryLane = 4194304; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return 1; + case 2: + return 2; + case 4: + return 4; + case 8: + return 8; + case 16: + return 16; + case 32: + return 32; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return lanes & 4194240; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return lanes & 130023424; + case 134217728: + return 134217728; + case 268435456: + return 268435456; + case 536870912: + return 536870912; + case 1073741824: + return 1073741824; + default: + return lanes; + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return 0; + var nextLanes = 0, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes, + nonIdlePendingLanes = pendingLanes & 268435455; + if (0 !== nonIdlePendingLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? (nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes))); + } else + (nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + 0 !== nonIdlePendingLanes + ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) + : 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes)); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) && + ((suspendedLanes = nextLanes & -nextLanes), + (pingedLanes = wipLanes & -wipLanes), + suspendedLanes >= pingedLanes || + (16 === suspendedLanes && 0 !== (pingedLanes & 4194240))) + ) + return wipLanes; + 0 !== (nextLanes & 4) && (nextLanes |= pendingLanes & 16); + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (pendingLanes = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function computeExpirationTime(lane, currentTime) { + switch (lane) { + case 1: + case 2: + case 4: + return currentTime + 250; + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return currentTime + 5e3; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return -1; + case 134217728: + case 268435456: + case 536870912: + case 1073741824: + return -1; + default: + return -1; + } +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$7 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$7; + remainingLanes[index$7] = 0; + eventTimes[index$7] = -1; + root[index$7] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$8 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$8; + (lane & entangledLanes) | (root[index$8] & entangledLanes) && + (root[index$8] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var currentUpdatePriority = 0; +function lanesToEventPriority(lanes) { + lanes &= -lanes; + return 1 < lanes + ? 4 < lanes + ? 0 !== (lanes & 268435455) + ? 16 + : 536870912 + : 4 + : 1; +} function shim() { throw Error( "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." @@ -1644,7 +1947,8 @@ function describeFunctionComponentFrame(fn, source) { ? describeComponentFrame(fn.displayName || fn.name || null, source, null) : ""; } -var valueStack = [], +var hasOwnProperty = Object.prototype.hasOwnProperty, + valueStack = [], index = -1; function createCursor(defaultValue) { return { current: defaultValue }; @@ -1698,13 +2002,13 @@ function pushTopLevelContextObject(fiber, context, didChange) { } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; - fiber = type.childContextTypes; + type = type.childContextTypes; if ("function" !== typeof instance.getChildContext) return parentContext; instance = instance.getChildContext(); for (var contextKey in instance) - if (!(contextKey in fiber)) + if (!(contextKey in type)) throw Error( - (getComponentName(type) || "Unknown") + + (getComponentNameFromFiber(fiber) || "Unknown") + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.' @@ -1740,304 +2044,39 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor); push(didPerformWorkStackCursor, didChange); } -var rendererID = null, - injectedHook = null, - Scheduler_now = Scheduler.unstable_now; -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, - fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { +var syncQueue = null, + includesLegacySyncCallbacks = !1, + isFlushingSyncQueue = !1; +function flushSyncCallbacks() { if (!isFlushingSyncQueue && null !== syncQueue) { isFlushingSyncQueue = !0; - var i = 0; + var i = 0, + previousUpdatePriority = currentUpdatePriority; try { var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); + for (currentUpdatePriority = 1; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } syncQueue = null; + includesLegacySyncCallbacks = !1; } catch (error) { throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), error); } finally { - isFlushingSyncQueue = !1; + (currentUpdatePriority = previousUpdatePriority), + (isFlushingSyncQueue = !1); } } + return null; } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, - hasOwnProperty = Object.prototype.hasOwnProperty; +var objectIs = "function" === typeof Object.is ? Object.is : is; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2094,14 +2133,14 @@ function resolveDefaultProps(Component, baseProps) { var valueCursor = createCursor(null), currentlyRenderingFiber = null, lastContextDependency = null, - lastContextWithAllBitsObserved = null; + lastFullyObservedContext = null; function resetContextDependencies() { - lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; + lastFullyObservedContext = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue2 = currentValue; + context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2121,44 +2160,41 @@ function scheduleWorkOnParentPath(parent, renderLanes) { } function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; - lastContextWithAllBitsObserved = lastContextDependency = null; + lastFullyObservedContext = lastContextDependency = null; workInProgress = workInProgress.dependencies; null !== workInProgress && null !== workInProgress.firstContext && (0 !== (workInProgress.lanes & renderLanes) && (didReceiveUpdate = !0), (workInProgress.firstContext = null)); } -function readContext(context, observedBits) { - if ( - lastContextWithAllBitsObserved !== context && - !1 !== observedBits && - 0 !== observedBits - ) { - if ("number" !== typeof observedBits || 1073741823 === observedBits) - (lastContextWithAllBitsObserved = context), (observedBits = 1073741823); - observedBits = { context: context, observedBits: observedBits, next: null }; - if (null === lastContextDependency) { +function readContext(context) { + var value = context._currentValue2; + if (lastFullyObservedContext !== context) + if ( + ((context = { context: context, memoizedValue: value, next: null }), + null === lastContextDependency) + ) { if (null === currentlyRenderingFiber) throw 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; + lastContextDependency = context; currentlyRenderingFiber.dependencies = { lanes: 0, - firstContext: observedBits, + firstContext: context, responders: null }; - } else lastContextDependency = lastContextDependency.next = observedBits; - } - return context._currentValue2; + } else lastContextDependency = lastContextDependency.next = context; + return value; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2184,14 +2220,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 4194240))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2260,111 +2314,111 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + 0 !== pendingQueue.lane && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2420,7 +2474,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2431,7 +2486,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2441,7 +2497,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2513,7 +2570,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && @@ -2535,7 +2591,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var isArray = Array.isArray; function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2588,25 +2643,22 @@ function coerceRef(returnFiber, current, element) { return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if ("textarea" !== returnFiber.type) - throw 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) + - "). If you meant to render a collection of children, use an array instead." - ); + returnFiber = Object.prototype.toString.call(newChild); + throw Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === returnFiber + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : returnFiber) + + "). If you meant to render a collection of children, use an array instead." + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2638,16 +2690,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2662,7 +2714,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2751,7 +2812,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (newChild = createFiberFromFragment( newChild, @@ -2776,22 +2837,14 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key ? null : updateFragment(returnFiber, oldFiber, newChild, lanes, null); @@ -2819,15 +2872,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -2838,7 +2883,7 @@ function ChildReconciler(shouldTrackSideEffects) { updatePortal(returnFiber, existingChildren, newChild, lanes) ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (existingChildren = existingChildren.get(newIdx) || null), updateFragment(returnFiber, existingChildren, newChild, lanes, null) @@ -3021,55 +3066,49 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.type === REACT_FRAGMENT_TYPE && null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); - var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) + if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; + var key = newChild.key; for ( isUnkeyedTopLevelFragment = currentFirstChild; null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + if (isUnkeyedTopLevelFragment.key === key) { + key = newChild.type; + if (key === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === key) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3145,6 +3184,22 @@ function ChildReconciler(shouldTrackSideEffects) { } return placeSingleChild(returnFiber); } + if (isArrayImpl(newChild)) + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + if (getIteratorFn(newChild)) + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + throwOnInvalidObjectType(returnFiber, newChild); + } if ("string" === typeof newChild || "number" === typeof newChild) return ( (newChild = "" + newChild), @@ -3163,21 +3218,6 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); - if (isArray(newChild)) - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - if (getIteratorFn(newChild)) - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - isObject && throwOnInvalidObjectType(returnFiber, newChild); if ("undefined" === typeof newChild && !isUnkeyedTopLevelFragment) switch (returnFiber.tag) { case 1: @@ -3185,7 +3225,7 @@ function ChildReconciler(shouldTrackSideEffects) { case 11: case 15: throw Error( - (getComponentName(returnFiber.type) || "Component") + + (getComponentNameFromFiber(returnFiber) || "Component") + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." ); } @@ -3247,7 +3287,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3399,10 +3439,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3427,22 +3468,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3482,7 +3534,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3512,25 +3564,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$11 = 31 - clz32(lanes), - lane = 1 << index$11; - entanglements[index$11] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3557,6 +3597,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3582,6 +3624,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3630,7 +3674,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3638,10 +3682,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(1049600, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3702,19 +3746,18 @@ function updateMemo(nextCreate, deps) { return nextCreate; } function startTransition(setPending, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = 1; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }); + var previousPriority = currentUpdatePriority; + currentUpdatePriority = + 0 !== previousPriority && 4 > previousPriority ? previousPriority : 4; + setPending(!0); + var prevTransition = ReactCurrentBatchConfig$1.transition; + ReactCurrentBatchConfig$1.transition = 1; + try { + setPending(!1), callback(); + } finally { + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$1.transition = prevTransition); + } } function dispatchAction(fiber, queue, action) { var eventTime = requestEventTime(), @@ -3726,33 +3769,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 4194240) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3809,6 +3874,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3850,7 +3917,7 @@ var ContextOnlyDispatcher = { isPending = _mountState2[0]; _mountState2 = startTransition.bind(null, _mountState2[1]); mountWorkInProgressHook().memoizedState = _mountState2; - return [_mountState2, isPending]; + return [isPending, _mountState2]; }, useMutableSource: function(source, getSnapshot, subscribe) { var hook = mountWorkInProgressHook(); @@ -3899,8 +3966,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = updateReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -3941,8 +4009,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = rerenderReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -3984,7 +4053,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4060,14 +4129,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4084,30 +4154,39 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 1)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, current), - null - ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= nextProps; + } else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4117,7 +4196,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4142,7 +4221,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4302,7 +4381,8 @@ function updateClassComponent( oldState, newState, oldContext - )) + ) || + !1) ? (getDerivedStateFromProps || ("function" !== typeof instance.UNSAFE_componentWillUpdate && "function" !== typeof instance.componentWillUpdate) || @@ -4317,7 +4397,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4325,7 +4405,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4339,7 +4419,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4360,7 +4440,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4404,18 +4484,21 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; +} function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4432,7 +4515,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4444,9 +4529,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), + (workInProgress.lanes = 4194304), current ); renderLanes = createFiberFromOffscreen( @@ -4472,8 +4559,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4500,8 +4590,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4524,7 +4617,7 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren)) : (progressedPrimaryFragment = createFiberFromOffscreen( @@ -4557,13 +4650,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4573,26 +4667,22 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + var mode = workInProgress.mode; + current = current.child; + var currentFallbackChildFragment = current.sibling, + primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 1) && workInProgress.child !== current ? ((primaryChildren = workInProgress.child), (primaryChildren.childLanes = 0), (primaryChildren.pendingProps = primaryChildProps), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4617,8 +4707,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4628,16 +4717,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4646,9 +4733,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4671,7 +4758,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4692,8 +4779,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4715,19 +4801,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4737,25 +4815,33 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } - return null; + return workInProgress.child; +} +function hadNoMutationsEffects(current, completedWork) { + if (null !== current && current.child === completedWork.child) return !0; + if (0 !== (completedWork.flags & 16)) return !1; + for (current = completedWork.child; null !== current; ) { + if (0 !== (current.flags & 6454) || 0 !== (current.subtreeFlags & 6454)) + return !1; + current = current.sibling; + } + return !0; } var appendAllChildren, updateHostContainer, @@ -4872,21 +4958,24 @@ function appendAllChildrenToContainer( node = node.sibling; } } -updateHostContainer = function(workInProgress) { +updateHostContainer = function(current, workInProgress) { var portalOrRoot = workInProgress.stateNode; - if (null !== workInProgress.firstEffect) { - var container = portalOrRoot.containerInfo, - newChildSet = createChildNodeSet(container); + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); portalOrRoot.pendingChildren = newChildSet; workInProgress.flags |= 4; - completeRoot(container, newChildSet); + completeRoot(current, newChildSet); } }; updateHostComponent$1 = function(current, workInProgress, type, newProps) { type = current.stateNode; var oldProps = current.memoizedProps; - if ((current = null === workInProgress.firstEffect) && oldProps === newProps) + if ( + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps + ) workInProgress.stateNode = type; else { var recyclableInstance = workInProgress.stateNode; @@ -4904,15 +4993,15 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { current && null === updatePayload ? (workInProgress.stateNode = type) : ((newProps = updatePayload), - (recyclableInstance = type.node), + (oldProps = type.node), (type = { node: current ? null !== newProps - ? cloneNodeWithNewProps(recyclableInstance, newProps) - : cloneNode(recyclableInstance) + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4958,6 +5047,30 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (lastTailNode$64.sibling = null); } } +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$65 = completedWork.child; null !== child$65; ) + (newChildLanes |= child$65.lanes | child$65.childLanes), + (subtreeFlags |= child$65.subtreeFlags & 1835008), + (subtreeFlags |= child$65.flags & 1835008), + (child$65.return = completedWork), + (child$65 = child$65.sibling); + else + for (child$65 = completedWork.child; null !== child$65; ) + (newChildLanes |= child$65.lanes | child$65.childLanes), + (subtreeFlags |= child$65.subtreeFlags), + (subtreeFlags |= child$65.flags), + (child$65.return = completedWork), + (child$65 = child$65.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4971,76 +5084,81 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); else { if (!newProps) { if (null === workInProgress.stateNode) throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); + bubbleProperties(workInProgress); return null; } requiredContext(contextStackCursor$1.current); current = nextReactTag; nextReactTag += 2; - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); - rootContainerInstance = createNode( + renderLanes = createNode( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderLanes, + type, newProps, workInProgress ); - current = { node: rootContainerInstance, canonical: current }; + current = { node: renderLanes, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 128); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5056,25 +5174,25 @@ function completeWork(current, workInProgress, renderLanes) { "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); current = requiredContext(rootInstanceStackCursor.current); - rootContainerInstance = requiredContext(contextStackCursor$1.current); + renderLanes = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - rootContainerInstance, + renderLanes, workInProgress ); } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5089,82 +5207,92 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } newProps && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderLanes = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), + (renderLanes = newProps), + (type = current), + (renderLanes.flags &= 1835010), + (updatePayload = renderLanes.alternate), null === updatePayload - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = renderLanes), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null)) - : ((rootContainerInstance.childLanes = - updatePayload.childLanes), - (rootContainerInstance.lanes = updatePayload.lanes), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = + ? ((renderLanes.childLanes = 0), + (renderLanes.lanes = type), + (renderLanes.child = null), + (renderLanes.subtreeFlags = 0), + (renderLanes.memoizedProps = null), + (renderLanes.memoizedState = null), + (renderLanes.updateQueue = null), + (renderLanes.dependencies = null), + (renderLanes.stateNode = null)) + : ((renderLanes.childLanes = updatePayload.childLanes), + (renderLanes.lanes = updatePayload.lanes), + (renderLanes.child = updatePayload.child), + (renderLanes.subtreeFlags = 0), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = + (renderLanes.memoizedState = updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (rootContainerInstance.type = updatePayload.type), - (renderLanes = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderLanes + (renderLanes.updateQueue = updatePayload.updateQueue), + (renderLanes.type = updatePayload.type), + (type = updatePayload.dependencies), + (renderLanes.dependencies = + null === type ? null : { - lanes: renderLanes.lanes, - firstContext: renderLanes.firstContext + lanes: type.lanes, + firstContext: type.firstContext })), (newProps = newProps.sibling); push( @@ -5175,78 +5303,74 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; case 22: case 23: return ( popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), null !== current && - (null !== current.memoizedState) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 1)) || + bubbleProperties(workInProgress), null ); } @@ -5261,8 +5385,8 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null; case 3: popHostContainer(); @@ -5270,11 +5394,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5282,8 +5406,8 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null ); case 19: @@ -5291,10 +5415,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5373,152 +5499,163 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$81 = finishedRoot.create; - finishedRoot.destroy = create$81(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$81 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$81; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$81 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$81, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode.canonical; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$82 = effect.create; + effect.destroy = create$82(); } - return; - case 5: - null === current && finishedWork.flags & 4 && shim(); - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } -function detachFiberMutation(fiber) { - fiber.alternate = null; +function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; + null !== alternate && + ((fiber.alternate = null), detachFiberAfterEffects(alternate)); fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function commitWork(current, finishedWork) { @@ -5527,19 +5664,7 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedWork = current = current.next; - do { - if (3 === (finishedWork.tag & 3)) { - var destroy = finishedWork.destroy; - finishedWork.destroy = void 0; - void 0 !== destroy && destroy(); - } - finishedWork = finishedWork.next; - } while (finishedWork !== current); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 12: return; @@ -5560,7 +5685,6 @@ function commitWork(current, finishedWork) { case 1: case 5: case 6: - case 20: break a; case 3: case 4: @@ -5585,83 +5709,305 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; -} -var ceil = Math.ceil, - ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - executionContext = 0, - workInProgressRoot = null, - workInProgress = null, - workInProgressRootRenderLanes = 0, - subtreeRenderLanes = 0, - subtreeRenderLanesCursor = createCursor(0), - workInProgressRootExitStatus = 0, - workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, - workInProgressRootSkippedLanes = 0, - workInProgressRootUpdatedLanes = 0, - workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, - globalMostRecentFallbackTime = 0, - workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, - hasUncaughtError = !1, - firstUncaughtError = null, - legacyErrorBoundariesThatAlreadyFailed = null, +function commitMutationEffects(root, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) { + var childToDelete = firstChild[i]; + try { + a: for (var node = childToDelete; ; ) { + var current = node; + if ( + injectedHook && + "function" === typeof injectedHook.onCommitFiberUnmount + ) + try { + injectedHook.onCommitFiberUnmount(rendererID, current); + } catch (err) {} + switch (current.tag) { + case 0: + case 11: + case 14: + case 15: + var updateQueue = current.updateQueue; + if (null !== updateQueue) { + var lastEffect = updateQueue.lastEffect; + if (null !== lastEffect) { + var firstEffect = lastEffect.next, + effect = firstEffect; + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + if (void 0 !== destroy && 0 !== (tag & 2)) { + _effect = current; + var nearestMountedAncestor = root; + try { + destroy(); + } catch (error) { + captureCommitPhaseError( + _effect, + nearestMountedAncestor, + error + ); + } + } + effect = effect.next; + } while (effect !== firstEffect); + } + } + break; + case 1: + safelyDetachRef(current, root); + var instance = current.stateNode; + if ("function" === typeof instance.componentWillUnmount) + try { + (effect = current), + (_effect = instance), + (_effect.props = effect.memoizedProps), + (_effect.state = effect.memoizedState), + _effect.componentWillUnmount(); + } catch (unmountError) { + captureCommitPhaseError(current, root, unmountError); + } + break; + case 5: + safelyDetachRef(current, root); + break; + case 4: + createChildNodeSet(current.stateNode.containerInfo); + } + if (null !== node.child) + (node.child.return = node), (node = node.child); + else { + if (node === childToDelete) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === childToDelete) + break a; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + } + var alternate = childToDelete.alternate; + null !== alternate && (alternate.return = null); + childToDelete.return = null; + } catch (error) { + captureCommitPhaseError(childToDelete, root, error); + } + } + firstChild = root.child; + if (0 !== (root.subtreeFlags & 6454) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var flags = root.flags; + if (flags & 256) { + var current$jscomp$0 = root.alternate; + if (null !== current$jscomp$0) { + var currentRef = current$jscomp$0.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + root.flags &= -3; + break; + case 6: + root.flags &= -3; + commitWork(root.alternate, root); + break; + case 2048: + root.flags &= -2049; + break; + case 2052: + root.flags &= -2049; + commitWork(root.alternate, root); + break; + case 4: + commitWork(root.alternate, root); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; + } + } +} +function commitLayoutEffects(finishedWork) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; + try { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, firstChild); + break; + case 1: + var instance = firstChild.stateNode; + if (firstChild.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + firstChild.elementType === firstChild.type + ? current.memoizedProps + : resolveDefaultProps( + firstChild.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = firstChild.updateQueue; + null !== updateQueue && + commitUpdateQueue(firstChild, updateQueue, instance); + break; + case 3: + var updateQueue$83 = firstChild.updateQueue; + if (null !== updateQueue$83) { + current = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { + case 5: + current = firstChild.child.stateNode.canonical; + break; + case 1: + current = firstChild.child.stateNode; + } + commitUpdateQueue(firstChild, updateQueue$83, current); + } + break; + case 5: + null === current && firstChild.flags & 4 && shim(); + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (firstChild.flags & 256) { + current = void 0; + var ref = firstChild.ref; + if (null !== ref) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { + case 5: + current = instance$jscomp$0.canonical; + break; + default: + current = instance$jscomp$0; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + } + if (firstChild === fiber) { + nextEffect = null; + break; + } + current = firstChild.sibling; + if (null !== current) { + current.return = firstChild.return; + nextEffect = current; + break; + } + nextEffect = firstChild.return; + } + } +} +var ceil = Math.ceil, + ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, + executionContext = 0, + workInProgressRoot = null, + workInProgress = null, + workInProgressRootRenderLanes = 0, + subtreeRenderLanes = 0, + subtreeRenderLanesCursor = createCursor(0), + workInProgressRootExitStatus = 0, + workInProgressRootFatalError = null, + workInProgressRootSkippedLanes = 0, + workInProgressRootUpdatedLanes = 0, + workInProgressRootPingedLanes = 0, + globalMostRecentFallbackTime = 0, + workInProgressRootRenderTargetTime = Infinity, + hasUncaughtError = !1, + firstUncaughtError = null, + legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, - pendingPassiveEffectsRenderPriority = 90, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], - rootsWithPendingDiscreteUpdates = null, + pendingPassiveEffectsLanes = 0, nestedUpdateCount = 0, rootWithNestedUpdates = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { - return 0 !== (executionContext & 48) + return 0 !== (executionContext & 24) ? now() : -1 !== currentEventTime ? currentEventTime : (currentEventTime = now()); } function requestUpdateLane(fiber) { - fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } - fiber = getCurrentPriorityLevel(); - 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) - : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); - return fiber; + if (0 === (fiber.mode & 1)) return 1; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); + fiber = currentUpdatePriority; + return 0 !== fiber ? fiber : 16; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (50 < nestedUpdateCount) @@ -5670,28 +6016,23 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { 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 = markUpdateLaneFromFiberToRoot(fiber, lane); - if (null === fiber) return null; - markRootUpdated(fiber, lane, eventTime); - fiber === workInProgressRoot && + var root = markUpdateLaneFromFiberToRoot(fiber, lane); + if (null === root) return null; + markRootUpdated(root, lane, eventTime); + root === workInProgressRoot && ((workInProgressRootUpdatedLanes |= lane), 4 === workInProgressRootExitStatus && - markRootSuspended$1(fiber, workInProgressRootRenderLanes)); - var priorityLevel = getCurrentPriorityLevel(); + markRootSuspended$1(root, workInProgressRootRenderLanes)); 1 === lane - ? 0 !== (executionContext & 8) && 0 === (executionContext & 48) - ? performSyncWorkOnRoot(fiber) - : (ensureRootIsScheduled(fiber, eventTime), + ? 0 !== (executionContext & 4) && 0 === (executionContext & 24) + ? performSyncWorkOnRoot(root) + : (ensureRootIsScheduled(root, eventTime), 0 === executionContext && + 0 === (fiber.mode & 1) && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue())) - : (0 === (executionContext & 4) || - (98 !== priorityLevel && 99 !== priorityLevel) || - (null === rootsWithPendingDiscreteUpdates - ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) - : rootsWithPendingDiscreteUpdates.add(fiber)), - ensureRootIsScheduled(fiber, eventTime)); - mostRecentlyUpdatedRoot = fiber; + includesLegacySyncCallbacks && flushSyncCallbacks())) + : ensureRootIsScheduled(root, eventTime); + return root; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -5720,17 +6061,8 @@ function ensureRootIsScheduled(root, currentTime) { lane = 1 << index$5, expirationTime = expirationTimes[index$5]; if (-1 === expirationTime) { - if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { - expirationTime = currentTime; - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; - expirationTimes[index$5] = - 10 <= priority - ? expirationTime + 250 - : 6 <= priority - ? expirationTime + 5e3 - : -1; - } + if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) + expirationTimes[index$5] = computeExpirationTime(lane, currentTime); } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } @@ -5738,47 +6070,58 @@ function ensureRootIsScheduled(root, currentTime) { root, root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); - currentTime = return_highestLanePriority; if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode), + null !== existingCallbackNode && cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); + (root.callbackPriority = 0); + else if ( + ((currentTime = suspendedLanes & -suspendedLanes), + root.callbackPriority !== currentTime) + ) { + null != existingCallbackNode && cancelCallback(existingCallbackNode); + if (1 === currentTime) + 0 === root.tag + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + (includesLegacySyncCallbacks = !0), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)) + : ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), + (existingCallbackNode = null); + else { + switch (lanesToEventPriority(suspendedLanes)) { + case 1: + existingCallbackNode = ImmediatePriority; + break; + case 4: + existingCallbackNode = UserBlockingPriority; + break; + case 16: + existingCallbackNode = NormalPriority; + break; + case 536870912: + existingCallbackNode = IdlePriority; + break; + default: + existingCallbackNode = NormalPriority; + } + existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ); } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); root.callbackPriority = currentTime; root.callbackNode = existingCallbackNode; } } -function performConcurrentWorkOnRoot(root) { +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; - if (0 !== (executionContext & 48)) + currentEventTransitionLane = 0; + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; if (flushPassiveEffects() && root.callbackNode !== originalCallbackNode) @@ -5788,41 +6131,45 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - var exitStatus = lanes; - var prevExecutionContext = executionContext; - executionContext |= 16; - var prevDispatcher = pushDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== exitStatus - ) - (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, exitStatus); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = prevExecutionContext; - null !== workInProgress - ? (exitStatus = 0) - : ((workInProgressRoot = null), - (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && - ((executionContext |= 64), + var JSCompiler_inline_result = + 0 !== (lanes & root.expiredLanes) ? !1 : 0 === (lanes & 30); + if (JSCompiler_inline_result && !didTimeout) { + didTimeout = lanes; + JSCompiler_inline_result = executionContext; + executionContext |= 8; + var prevDispatcher = pushDispatcher(); + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== didTimeout + ) + (workInProgressRootRenderTargetTime = now() + 500), + prepareFreshStack(root, didTimeout); + do + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + ReactCurrentDispatcher$2.current = prevDispatcher; + executionContext = JSCompiler_inline_result; + null !== workInProgress + ? (didTimeout = 0) + : ((workInProgressRoot = null), + (workInProgressRootRenderLanes = 0), + (didTimeout = workInProgressRootExitStatus)); + } else didTimeout = renderRootSync(root, lanes); + if (0 !== didTimeout) { + 2 === didTimeout && + ((executionContext |= 32), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + (JSCompiler_inline_result = getLanesToRetrySynchronouslyOnError(root)), + 0 !== JSCompiler_inline_result && + ((lanes = JSCompiler_inline_result), + (didTimeout = renderRootSync(root, JSCompiler_inline_result)))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -5830,7 +6177,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -5840,20 +6187,20 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 130023424) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; - prevExecutionContext = root.suspendedLanes; - if ((prevExecutionContext & lanes) !== lanes) { + JSCompiler_inline_result = root.suspendedLanes; + if ((JSCompiler_inline_result & lanes) !== lanes) { requestEventTime(); - root.pingedLanes |= root.suspendedLanes & prevExecutionContext; + root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result; break; } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -5861,16 +6208,17 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; - for (prevExecutionContext = -1; 0 < lanes; ) { + if ((lanes & 4194240) === lanes) break; + didTimeout = root.eventTimes; + for (JSCompiler_inline_result = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); prevDispatcher = 1 << index$4; - index$4 = exitStatus[index$4]; - index$4 > prevExecutionContext && (prevExecutionContext = index$4); + index$4 = didTimeout[index$4]; + index$4 > JSCompiler_inline_result && + (JSCompiler_inline_result = index$4); lanes &= ~prevDispatcher; } - lanes = prevExecutionContext; + lanes = JSCompiler_inline_result; lanes = now() - lanes; lanes = (120 > lanes @@ -5913,33 +6261,26 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$9 = 31 - clz32(suspendedLanes), - lane = 1 << index$9; - root[index$9] = -1; + var index$6 = 31 - clz32(suspendedLanes), + lane = 1 << index$6; + root[index$6] = -1; suspendedLanes &= ~lane; } } function performSyncWorkOnRoot(root) { - if (0 !== (executionContext & 48)) + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( - root === workInProgressRoot && - 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); - 0 !== root.tag && - 2 === exitStatus && - ((executionContext |= 64), - root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + var lanes = getNextLanes(root, 0); + if (0 === (lanes & 1)) return ensureRootIsScheduled(root, now()), null; + var exitStatus = renderRootSync(root, lanes); + if (0 !== root.tag && 2 === exitStatus) { + executionContext |= 32; + root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + 0 !== errorRetryLanes && + ((lanes = errorRetryLanes), (exitStatus = renderRootSync(root, lanes))); + } if (1 === exitStatus) throw ((exitStatus = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -5952,11 +6293,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -5996,7 +6332,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6006,10 +6342,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6045,15 +6400,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6064,15 +6422,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$76 = returnFiber; + workInProgress$77 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$76.tag)) { - var nextState = workInProgress$76.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { + var nextState = workInProgress$77.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$76.memoizedProps; + var props = workInProgress$77.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6084,16 +6442,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$76.updateQueue; + var wakeables = workInProgress$77.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$76.updateQueue = updateQueue; + workInProgress$77.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$76.mode & 2)) { - workInProgress$76.flags |= 64; + if ( + 0 === (workInProgress$77.mode & 1) && + workInProgress$77 !== returnFiber + ) { + workInProgress$77.flags |= 128; sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6124,61 +6485,61 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$76.flags |= 8192; - workInProgress$76.lanes = thrownValue; + workInProgress$77.flags |= 16384; + workInProgress$77.lanes = thrownValue; break a; } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); value = Error( - (getComponentName(sourceFiber.type) || "A React component") + + (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." ); } 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$76 = returnFiber; + workInProgress$77 = returnFiber; do { - switch (workInProgress$76.tag) { + switch (workInProgress$77.tag) { case 3: root = value; - workInProgress$76.flags |= 8192; + workInProgress$77.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$77 = createRootErrorUpdate( - workInProgress$76, + workInProgress$77.lanes |= thrownValue; + var update$78 = createRootErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$77); + enqueueCapturedUpdate(workInProgress$77, update$78); break a; case 1: root = value; - var ctor = workInProgress$76.type, - instance = workInProgress$76.stateNode; + var ctor = workInProgress$77.type, + instance = workInProgress$77.stateNode; if ( - 0 === (workInProgress$76.flags & 64) && + 0 === (workInProgress$77.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$76.flags |= 8192; + workInProgress$77.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$80 = createClassErrorUpdate( - workInProgress$76, + workInProgress$77.lanes |= thrownValue; + var update$81 = createClassErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$80); + enqueueCapturedUpdate(workInProgress$77, update$81); break a; } } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6198,7 +6559,7 @@ function pushDispatcher() { } function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; - executionContext |= 16; + executionContext |= 8; var prevDispatcher = pushDispatcher(); (workInProgressRoot === root && workInProgressRootRenderLanes === lanes) || prepareFreshStack(root, lanes); @@ -6225,7 +6586,7 @@ function workLoopSync() { for (; null !== workInProgress; ) performUnitOfWork(workInProgress); } function workLoopConcurrent() { - for (; null !== workInProgress && !Scheduler_shouldYield(); ) + for (; null !== workInProgress && !shouldYield(); ) performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { @@ -6239,47 +6600,25 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - current = completeWork(current, completedWork, subtreeRenderLanes); - if (null !== current) { - workInProgress = current; - return; - } - current = completedWork; + if (0 === (completedWork.flags & 8192)) { if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) + ((current = completeWork(current, completedWork, subtreeRenderLanes)), + null !== current) ) { - for (var newChildLanes = 0, child = current.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (child = child.sibling); - current.childLanes = newChildLanes; + workInProgress = current; + return; } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6291,16 +6630,25 @@ function completeUnitOfWork(unitOfWork) { 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } function commitRoot(root) { - var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig$2.transition; + try { + (ReactCurrentBatchConfig$2.transition = 0), + (currentUpdatePriority = 1), + commitRootImpl(root, previousUpdateLanePriority); + } finally { + (ReactCurrentBatchConfig$2.transition = prevTransition), + (currentUpdatePriority = previousUpdateLanePriority); + } return null; } function commitRootImpl(root, renderPriorityLevel) { do flushPassiveEffects(); while (null !== rootWithPendingPassiveEffects); - if (0 !== (executionContext & 48)) + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork; + var finishedWork = root.finishedWork, + lanes = root.finishedLanes; if (null === finishedWork) return null; root.finishedWork = null; root.finishedLanes = 0; @@ -6309,360 +6657,207 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$10 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$10; - remainingLanes$jscomp$0[index$10] = 0; - eventTimes[index$10] = -1; - expirationTimes[index$10] = -1; - noLongerPendingLanes &= ~lane; - } - null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && - rootsWithPendingDiscreteUpdates.has(root) && - rootsWithPendingDiscreteUpdates.delete(root); + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; - executionContext |= 32; - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; - nextEffect = remainingLanes; - do - try { - for (; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - nextEffect.flags &= -3; - break; - case 6: - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - eventTimes = nextEffect; - a: for (noLongerPendingLanes = expirationTimes = eventTimes; ; ) { - index$10 = noLongerPendingLanes; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, index$10); - } catch (err) {} - switch (index$10.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = index$10.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next; - lane = firstEffect; - do { - var _effect2 = lane, - destroy = _effect2.destroy, - tag = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (tag & 4)) - enqueuePendingPassiveHookEffectUnmount( - index$10, - lane - ); - else { - _effect2 = index$10; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } - } - lane = lane.next; - } while (lane !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(index$10); - var instance = index$10.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (lane = index$10), - (_effect2 = instance), - (_effect2.props = lane.memoizedProps), - (_effect2.state = lane.memoizedState), - _effect2.componentWillUnmount(); - } catch (unmountError) { - captureCommitPhaseError(index$10, unmountError); - } - break; - case 5: - safelyDetachRef(index$10); - break; - case 4: - createChildNodeSet(index$10.stateNode.containerInfo); - } - if (null !== noLongerPendingLanes.child) - (noLongerPendingLanes.child.return = noLongerPendingLanes), - (noLongerPendingLanes = noLongerPendingLanes.child); - else { - if (noLongerPendingLanes === expirationTimes) break; - for (; null === noLongerPendingLanes.sibling; ) { - if ( - null === noLongerPendingLanes.return || - noLongerPendingLanes.return === expirationTimes - ) - break a; - noLongerPendingLanes = noLongerPendingLanes.return; - } - noLongerPendingLanes.sibling.return = - noLongerPendingLanes.return; - noLongerPendingLanes = noLongerPendingLanes.sibling; - } - } - var alternate = eventTimes.alternate; - detachFiberMutation(eventTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$87) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$87); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { + remainingLanes = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = currentUpdatePriority; + currentUpdatePriority = 1; + var prevExecutionContext = executionContext; + executionContext |= 16; + ReactCurrentOwner$2.current = null; + commitBeforeMutationEffects(root, finishedWork); + commitMutationEffects(root, finishedWork); root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance$jscomp$0.canonical; - break; - default: - current = instance$jscomp$0; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$88) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$88); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; + commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - executionContext = remainingLanes$jscomp$0; + executionContext = prevExecutionContext; + currentUpdatePriority = previousPriority; + ReactCurrentBatchConfig$2.transition = remainingLanes; } else root.current = finishedWork; - if (rootDoesHavePassiveEffects) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (renderPriorityLevel = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((flags$jscomp$0 = nextEffect), - (flags$jscomp$0.sibling = null), - (flags$jscomp$0.stateNode = null)), - (nextEffect = renderPriorityLevel); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - 1 === remainingLanes + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - void 0, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), (root = firstUncaughtError), (firstUncaughtError = null), root); - if (0 !== (executionContext & 8)) return null; - flushSyncCallbackQueue(); + if (0 !== (executionContext & 4)) return null; + 0 !== (pendingPassiveEffectsLanes & 1) && + 0 !== root.tag && + flushPassiveEffects(); + flushSyncCallbacks(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { - if (90 !== pendingPassiveEffectsRenderPriority) { - var priorityLevel = - 97 < pendingPassiveEffectsRenderPriority - ? 97 - : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = 90; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); - } - return !1; -} -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function flushPassiveEffectsImpl() { - if (null === rootWithPendingPassiveEffects) return !1; - var root = rootWithPendingPassiveEffects; - rootWithPendingPassiveEffects = null; - if (0 !== (executionContext & 48)) - throw Error("Cannot flush passive effects while already rendering."); - var prevExecutionContext = executionContext; - executionContext |= 32; - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$93 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$93.destroy; - effect$93.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); - } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$93 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; + if (null !== rootWithPendingPassiveEffects) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), + prevTransition = ReactCurrentBatchConfig$2.transition, + previousPriority = currentUpdatePriority; try { - var create$97 = effect$93.create; - effect$93.destroy = create$97(); - } catch (error$98) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$98); + ReactCurrentBatchConfig$2.transition = 0; + currentUpdatePriority = 16 > renderPriority ? 16 : renderPriority; + if (null === rootWithPendingPassiveEffects) + var JSCompiler_inline_result = !1; + else { + renderPriority = rootWithPendingPassiveEffects; + rootWithPendingPassiveEffects = null; + pendingPassiveEffectsLanes = 0; + if (0 !== (executionContext & 24)) + throw Error("Cannot flush passive effects while already rendering."); + var prevExecutionContext = executionContext; + executionContext |= 16; + for (nextEffect = renderPriority.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + var sibling = fiber$jscomp$0.sibling, + returnFiber = fiber$jscomp$0.return; + if (fiber$jscomp$0 === fiberToDelete) { + detachFiberAfterEffects(fiber$jscomp$0); + nextEffect = null; + break; + } + if (null !== sibling) { + sibling.return = returnFiber; + nextEffect = sibling; + break; + } + nextEffect = returnFiber; + } + } + } + var previousFiber = fiber.alternate; + if (null !== previousFiber) { + var detachedChild = previousFiber.child; + if (null !== detachedChild) { + previousFiber.child = null; + do { + var detachedSibling = detachedChild.sibling; + detachedChild.sibling = null; + detachedChild = detachedSibling; + } while (null !== detachedChild); + } + } + nextEffect = fiber; + } + } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + b: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + var sibling$jscomp$0 = fiber.sibling; + if (null !== sibling$jscomp$0) { + sibling$jscomp$0.return = fiber.return; + nextEffect = sibling$jscomp$0; + break b; + } + nextEffect = fiber.return; + } + } + var finishedWork = renderPriority.current; + for (nextEffect = finishedWork; null !== nextEffect; ) { + child = nextEffect; + var firstChild = child.child; + if (0 !== (child.subtreeFlags & 1040) && null !== firstChild) + (firstChild.return = child), (nextEffect = firstChild); + else + b: for (child = finishedWork; null !== nextEffect; ) { + deletions = nextEffect; + if (0 !== (deletions.flags & 1024)) + try { + switch (deletions.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, deletions); + } + } catch (error) { + captureCommitPhaseError(deletions, deletions.return, error); + } + if (deletions === child) { + nextEffect = null; + break b; + } + var sibling$jscomp$1 = deletions.sibling; + if (null !== sibling$jscomp$1) { + sibling$jscomp$1.return = deletions.return; + nextEffect = sibling$jscomp$1; + break b; + } + nextEffect = deletions.return; + } + } + executionContext = prevExecutionContext; + flushSyncCallbacks(); + if ( + injectedHook && + "function" === typeof injectedHook.onPostCommitFiberRoot + ) + try { + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); + } catch (err) {} + JSCompiler_inline_result = !0; + } + return JSCompiler_inline_result; + } finally { + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$2.transition = prevTransition); } } - for (create$97 = root.current.firstEffect; null !== create$97; ) - (root = create$97.nextEffect), - (create$97.nextEffect = null), - create$97.flags & 8 && - ((create$97.sibling = null), (create$97.stateNode = null)), - (create$97 = root); - executionContext = prevExecutionContext; - flushSyncCallbackQueue(); - return !0; + return !1; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { sourceFiber = createCapturedValue(error, sourceFiber); @@ -6674,42 +6869,50 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { (markRootUpdated(rootFiber, 1, sourceFiber), ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6721,7 +6924,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 130023424) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6733,15 +6936,11 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); wakeable = 0; 0 === wakeable && - ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + (0 === (boundaryFiber.mode & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) - ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 130023424) && (nextRetryLane = 4194304))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6757,78 +6956,83 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateLanes; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, + if (0 === (renderLanes & updateLanes)) { + didReceiveUpdate = !1; + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer( workInProgress, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + break; + case 10: + updateLanes = workInProgress.type._context; + var nextValue = workInProgress.memoizedProps.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = nextValue; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); + return null !== workInProgress ? workInProgress.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; + case 19: + updateLanes = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; + } + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); + } + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -6840,22 +7044,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -6865,21 +7069,13 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; - "function" === typeof getDerivedStateFromProps && - applyDerivedStateFromProps( - workInProgress, - updateLanes, - getDerivedStateFromProps, - current - ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -6891,28 +7087,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6921,7 +7117,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6930,7 +7126,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6939,8 +7135,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -6948,7 +7144,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -6956,32 +7152,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -6992,19 +7188,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7044,16 +7239,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7090,27 +7285,15 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; - getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue2); - context$jscomp$0._currentValue2 = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + nextValue = workInProgress.pendingProps; + hasContext = workInProgress.memoizedProps; + var newValue = nextValue.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = newValue; + if (null !== hasContext) + if (objectIs(hasContext.value, newValue)) { if ( - getDerivedStateFromProps.children === context.children && + hasContext.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7122,76 +7305,71 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + newValue = workInProgress.child, + null !== newValue && (newValue.return = workInProgress); + null !== newValue; ) { - var list = context$jscomp$0.dependencies; + var list = newValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + hasContext = newValue.child; for ( var dependency = list.firstContext; null !== dependency; ) { - if ( - dependency.context === updateLanes && - 0 !== (dependency.observedBits & hasContext) - ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (dependency.context === updateLanes) { + if (1 === newValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = newValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + newValue.lanes |= renderLanes; + dependency = newValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(newValue.return, renderLanes); list.lanes |= renderLanes; break; } dependency = dependency.next; } } else - getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + hasContext = + 10 === newValue.tag + ? newValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; - if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + : newValue.child + : newValue.child; + if (null !== hasContext) hasContext.return = newValue; else - for ( - getDerivedStateFromProps = context$jscomp$0; - null !== getDerivedStateFromProps; - - ) { - if (getDerivedStateFromProps === workInProgress) { - getDerivedStateFromProps = null; + for (hasContext = newValue; null !== hasContext; ) { + if (hasContext === workInProgress) { + hasContext = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + newValue = hasContext.sibling; + if (null !== newValue) { + newValue.return = hasContext.return; + hasContext = newValue; break; } - getDerivedStateFromProps = getDerivedStateFromProps.return; + hasContext = hasContext.return; } - context$jscomp$0 = getDerivedStateFromProps; + newValue = hasContext; } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7199,28 +7377,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), - (hasContext = workInProgress.pendingProps), - (updateLanes = hasContext.children), + (nextValue = workInProgress.type), + (updateLanes = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7238,11 +7415,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7252,8 +7429,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7285,8 +7462,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; } @@ -7324,9 +7501,9 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null)); + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null)); + workInProgress.flags = current.flags & 1835008; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7361,24 +7538,22 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 4; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + mode |= 24; break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 2)), (type.elementType = REACT_PROFILER_TYPE), - (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), type ); case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.lanes = lanes), type @@ -7556,7 +7731,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7584,14 +7760,14 @@ batchedUpdatesImpl = function(fn, a) { (executionContext = prevExecutionContext), 0 === executionContext && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue()); + includesLegacySyncCallbacks && flushSyncCallbacks()); } }; var roots = new Map(), - devToolsConfig$jscomp$inline_865 = { + devToolsConfig$jscomp$inline_942 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.3-experimental-2d8d133e1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7606,11 +7782,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1054 = { - bundleType: devToolsConfig$jscomp$inline_865.bundleType, - version: devToolsConfig$jscomp$inline_865.version, - rendererPackageName: devToolsConfig$jscomp$inline_865.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_865.rendererConfig, +var internals$jscomp$inline_1180 = { + bundleType: devToolsConfig$jscomp$inline_942.bundleType, + version: devToolsConfig$jscomp$inline_942.version, + rendererPackageName: devToolsConfig$jscomp$inline_942.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_942.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7625,25 +7801,26 @@ var internals$jscomp$inline_1054 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_865.findFiberByHostInstance || + devToolsConfig$jscomp$inline_942.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, - getCurrentFiber: null + getCurrentFiber: null, + reconcilerVersion: "17.0.3-experimental-2d8d133e1" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1055 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1181 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1055.isDisabled && - hook$jscomp$inline_1055.supportsFiber + !hook$jscomp$inline_1181.isDisabled && + hook$jscomp$inline_1181.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1055.inject( - internals$jscomp$inline_1054 + (rendererID = hook$jscomp$inline_1181.inject( + internals$jscomp$inline_1180 )), - (injectedHook = hook$jscomp$inline_1055); + (injectedHook = hook$jscomp$inline_1181); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -7681,16 +7858,18 @@ exports.findHostInstance_DEPRECATED = function(componentOrHandle) { : componentOrHandle; }; exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { +exports.render = function(element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = createFiber(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } + root || + ((root = concurrentRoot ? 1 : 0), + (concurrentRoot = new FiberRootNode(containerTag, root, !1)), + (root = createFiber(3, null, null, 1 === root ? 1 : 0)), + (concurrentRoot.current = root), + (root.stateNode = concurrentRoot), + (root.memoizedState = { element: null }), + initializeUpdateQueue(root), + (root = concurrentRoot), + roots.set(containerTag, root)); updateContainer(element, root, null, callback); a: if (((element = root.current), element.child)) switch (element.child.tag) { @@ -7703,6 +7882,18 @@ exports.render = function(element, containerTag, callback) { else element = null; return element; }; +exports.sendAccessibilityEvent = function(handle, eventType) { + null != handle._nativeTag && + (handle._internalInstanceHandle + ? nativeFabricUIManager.sendAccessibilityEvent( + handle._internalInstanceHandle.stateNode.node, + eventType + ) + : ReactNativePrivateInterface.legacySendAccessibilityEvent( + handle._nativeTag, + eventType + )); +}; exports.stopSurface = function(containerTag) { var root = roots.get(containerTag); root && diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 5bb2ff1d2b3b06..cbf24e776743ba 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -7,15 +7,14 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<08382e61f6bfa261be904923b08bfce7>> */ "use strict"; require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), - Scheduler = require("scheduler"), - tracing = require("scheduler/tracing"); + Scheduler = require("scheduler"); function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -63,7 +62,8 @@ function invokeGuardedCallbackAndCatchFirstError( hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } } -var getFiberCurrentPropsFromNode = null, +var isArrayImpl = Array.isArray, + getFiberCurrentPropsFromNode = null, getInstanceFromNode = null, getNodeFromInstance = null; function executeDispatch(event, listener, inst) { @@ -75,7 +75,7 @@ function executeDispatch(event, listener, inst) { function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; - if (Array.isArray(dispatchListener)) + if (isArrayImpl(dispatchListener)) throw Error("executeDirectDispatch(...): Invalid `event`."); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) @@ -336,9 +336,9 @@ function accumulate(current, next) { ); return null == current ? next - : Array.isArray(current) + : isArrayImpl(current) ? current.concat(next) - : Array.isArray(next) + : isArrayImpl(next) ? [current].concat(next) : [current, next]; } @@ -348,12 +348,12 @@ function accumulateInto(current, next) { "accumulateInto(...): Accumulated items must not be null or undefined." ); if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; + if (isArrayImpl(current)) { + if (isArrayImpl(next)) return current.push.apply(current, next), current; current.push(next); return current; } - return Array.isArray(next) ? [current].concat(next) : [current, next]; + return isArrayImpl(next) ? [current].concat(next) : [current, next]; } function forEachAccumulated(arr, cb, scope) { Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); @@ -579,7 +579,7 @@ var ResponderEventPlugin = { b: { JSCompiler_temp = shouldSetEventType._dispatchListeners; targetInst = shouldSetEventType._dispatchInstances; - if (Array.isArray(JSCompiler_temp)) + if (isArrayImpl(JSCompiler_temp)) for ( depthA = 0; depthA < JSCompiler_temp.length && @@ -930,7 +930,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_220 = { +var injectedNamesToPlugins$jscomp$inline_221 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -965,34 +965,34 @@ var injectedNamesToPlugins$jscomp$inline_220 = { } } }, - isOrderingDirty$jscomp$inline_221 = !1, - pluginName$jscomp$inline_222; -for (pluginName$jscomp$inline_222 in injectedNamesToPlugins$jscomp$inline_220) + isOrderingDirty$jscomp$inline_222 = !1, + pluginName$jscomp$inline_223; +for (pluginName$jscomp$inline_223 in injectedNamesToPlugins$jscomp$inline_221) if ( - injectedNamesToPlugins$jscomp$inline_220.hasOwnProperty( - pluginName$jscomp$inline_222 + injectedNamesToPlugins$jscomp$inline_221.hasOwnProperty( + pluginName$jscomp$inline_223 ) ) { - var pluginModule$jscomp$inline_223 = - injectedNamesToPlugins$jscomp$inline_220[pluginName$jscomp$inline_222]; + var pluginModule$jscomp$inline_224 = + injectedNamesToPlugins$jscomp$inline_221[pluginName$jscomp$inline_223]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_222) || - namesToPlugins[pluginName$jscomp$inline_222] !== - pluginModule$jscomp$inline_223 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_223) || + namesToPlugins[pluginName$jscomp$inline_223] !== + pluginModule$jscomp$inline_224 ) { - if (namesToPlugins[pluginName$jscomp$inline_222]) + if (namesToPlugins[pluginName$jscomp$inline_223]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_222 + + pluginName$jscomp$inline_223 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_222 - ] = pluginModule$jscomp$inline_223; - isOrderingDirty$jscomp$inline_221 = !0; + pluginName$jscomp$inline_223 + ] = pluginModule$jscomp$inline_224; + isOrderingDirty$jscomp$inline_222 = !0; } } -isOrderingDirty$jscomp$inline_221 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_222 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -1007,13 +1007,27 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - (from || to).stateNode.canonical._internalInstanceHandle || - (null !== to - ? ReactNativePrivateInterface.UIManager.setJSResponder( - to.stateNode.canonical._nativeTag, - blockNativeResponder - ) - : ReactNativePrivateInterface.UIManager.clearJSResponder()); + var fromOrTo = from || to; + (fromOrTo = fromOrTo && fromOrTo.stateNode) && + fromOrTo.canonical._internalInstanceHandle + ? (from && + nativeFabricUIManager.setIsJSResponder( + from.stateNode.node, + !1, + blockNativeResponder || !1 + ), + to && + nativeFabricUIManager.setIsJSResponder( + to.stateNode.node, + !0, + blockNativeResponder || !1 + )) + : null !== to + ? ReactNativePrivateInterface.UIManager.setJSResponder( + to.stateNode.canonical._nativeTag, + blockNativeResponder + ) + : ReactNativePrivateInterface.UIManager.clearJSResponder(); } }); var ReactSharedInternals = @@ -1090,13 +1104,18 @@ function getComponentNameFromType(type) { return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; - innerType = innerType.displayName || innerType.name || ""; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: return ( - type.displayName || - ("" !== innerType ? "ForwardRef(" + innerType + ")" : "ForwardRef") + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" ); - case REACT_MEMO_TYPE: - return getComponentNameFromType(type.type); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; @@ -1308,7 +1327,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) + if (isArrayImpl(node)) for (var i = node.length; i-- && 0 < removedKeyCount; ) restoreDeletedValuesInNestedArray( updatePayload, @@ -1354,9 +1373,9 @@ function diffNestedProperty( : prevProp ? clearNestedProperty(updatePayload, prevProp, validAttributes) : updatePayload; - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) + if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { var minLength = prevProp.length < nextProp.length ? prevProp.length : nextProp.length, i; @@ -1381,7 +1400,7 @@ function diffNestedProperty( ); return updatePayload; } - return Array.isArray(prevProp) + return isArrayImpl(prevProp) ? diffProperties( updatePayload, ReactNativePrivateInterface.flattenStyle(prevProp), @@ -1397,7 +1416,7 @@ function diffNestedProperty( } function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) return updatePayload; - if (!Array.isArray(nextProp)) + if (!isArrayImpl(nextProp)) return diffProperties( updatePayload, emptyObject, @@ -1414,7 +1433,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { } function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) return updatePayload; - if (!Array.isArray(prevProp)) + if (!isArrayImpl(prevProp)) return diffProperties( updatePayload, prevProp, @@ -1532,7 +1551,7 @@ function executeDispatchesAndReleaseTopLevel(e) { if (e) { var dispatchListeners = e._dispatchListeners, dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) + if (isArrayImpl(dispatchListeners)) for ( var i = 0; i < dispatchListeners.length && !e.isPropagationStopped(); @@ -1592,6 +1611,46 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } +var scheduleCallback = Scheduler.unstable_scheduleCallback, + cancelCallback = Scheduler.unstable_cancelCallback, + shouldYield = Scheduler.unstable_shouldYield, + requestPaint = Scheduler.unstable_requestPaint, + now = Scheduler.unstable_now, + ImmediatePriority = Scheduler.unstable_ImmediatePriority, + UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + NormalPriority = Scheduler.unstable_NormalPriority, + IdlePriority = Scheduler.unstable_IdlePriority, + rendererID = null, + injectedHook = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function onCommitRoot(root, eventPriority) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + var didError = 128 === (root.current.flags & 128); + switch (eventPriority) { + case 1: + var schedulerPriority = ImmediatePriority; + break; + case 4: + schedulerPriority = UserBlockingPriority; + break; + case 16: + schedulerPriority = NormalPriority; + break; + case 536870912: + schedulerPriority = IdlePriority; + break; + default: + schedulerPriority = NormalPriority; + } + injectedHook.onCommitFiberRoot( + rendererID, + root, + schedulerPriority, + didError + ); + } catch (err) {} +} var nextTransitionLane = 64, nextRetryLane = 4194304; function getHighestPriorityLanes(lanes) { @@ -1650,18 +1709,19 @@ function getNextLanes(root, wipLanes) { suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes, nonIdlePendingLanes = pendingLanes & 268435455; - 0 !== nonIdlePendingLanes - ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes), - 0 !== pendingLanes - ? (nextLanes = getHighestPriorityLanes(pendingLanes)) - : ((pingedLanes &= nonIdlePendingLanes), - 0 !== pingedLanes && - (nextLanes = getHighestPriorityLanes(pingedLanes)))) - : ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + if (0 !== nonIdlePendingLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? (nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes))); + } else + (nonIdlePendingLanes = pendingLanes & ~suspendedLanes), 0 !== nonIdlePendingLanes ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) : 0 !== pingedLanes && - (nextLanes = getHighestPriorityLanes(pingedLanes))); + (nextLanes = getHighestPriorityLanes(pingedLanes)); if (0 === nextLanes) return 0; if ( 0 !== wipLanes && @@ -1673,13 +1733,16 @@ function getNextLanes(root, wipLanes) { (16 === suspendedLanes && 0 !== (pingedLanes & 4194240))) ) return wipLanes; + 0 === (root.current.mode & 32) && + 0 !== (nextLanes & 4) && + (nextLanes |= pendingLanes & 16); wipLanes = root.entangledLanes; if (0 !== wipLanes) for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (suspendedLanes = 31 - clz32(wipLanes)), - (pingedLanes = 1 << suspendedLanes), - (nextLanes |= root[suspendedLanes]), - (wipLanes &= ~pingedLanes); + (pendingLanes = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~suspendedLanes); return nextLanes; } function computeExpirationTime(lane, currentTime) { @@ -1707,12 +1770,13 @@ function computeExpirationTime(lane, currentTime) { case 524288: case 1048576: case 2097152: + return currentTime + 5e3; case 4194304: case 8388608: case 16777216: case 33554432: case 67108864: - return currentTime + 5e3; + return -1; case 134217728: case 268435456: case 536870912: @@ -1738,16 +1802,12 @@ function markRootUpdated(root, updateLane, eventTime) { updateLane = 31 - clz32(updateLane); root[updateLane] = eventTime; } -function markRootExpired(root, expiredLanes) { - root.entanglements[0] |= expiredLanes; - root.entangledLanes |= 1; - root.pendingLanes |= 1; -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; root.suspendedLanes = 0; root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; root.mutableReadLanes &= remainingLanes; root.entangledLanes &= remainingLanes; remainingLanes = root.entanglements; @@ -1906,7 +1966,8 @@ function describeFunctionComponentFrame(fn, source) { ? describeComponentFrame(fn.displayName || fn.name || null, source, null) : ""; } -var valueStack = [], +var hasOwnProperty = Object.prototype.hasOwnProperty, + valueStack = [], index = -1; function createCursor(defaultValue) { return { current: defaultValue }; @@ -2002,56 +2063,10 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor); push(didPerformWorkStackCursor, didChange); } -var scheduleCallback = Scheduler.unstable_scheduleCallback, - cancelCallback = Scheduler.unstable_cancelCallback, - shouldYield = Scheduler.unstable_shouldYield, - requestPaint = Scheduler.unstable_requestPaint, - now = Scheduler.unstable_now, - ImmediatePriority = Scheduler.unstable_ImmediatePriority, - UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority = Scheduler.unstable_NormalPriority, - IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var rendererID = null, - injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; -function onCommitRoot(root, eventPriority) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - var didError = 128 === (root.current.flags & 128); - switch (eventPriority) { - case 1: - var schedulerPriority = ImmediatePriority; - break; - case 4: - schedulerPriority = UserBlockingPriority; - break; - case 16: - schedulerPriority = NormalPriority; - break; - case 536870912: - schedulerPriority = IdlePriority; - break; - default: - schedulerPriority = NormalPriority; - } - injectedHook.onCommitFiberRoot( - rendererID, - root, - schedulerPriority, - didError - ); - } catch (err) {} -} var syncQueue = null, + includesLegacySyncCallbacks = !1, isFlushingSyncQueue = !1; -function flushSyncCallbackQueue() { +function flushSyncCallbacks() { if (!isFlushingSyncQueue && null !== syncQueue) { isFlushingSyncQueue = !0; var i = 0, @@ -2064,9 +2079,10 @@ function flushSyncCallbackQueue() { while (null !== callback); } syncQueue = null; + includesLegacySyncCallbacks = !1; } catch (error) { throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), error); } finally { (currentUpdatePriority = previousUpdatePriority), @@ -2079,8 +2095,7 @@ var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, - hasOwnProperty = Object.prototype.hasOwnProperty; +var objectIs = "function" === typeof Object.is ? Object.is : is; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2379,6 +2394,7 @@ function processUpdateQueue( } } null !== pendingQueue.callback && + 0 !== pendingQueue.lane && ((workInProgress$jscomp$0.flags |= 64), (updateLane = queue.effects), null === updateLane @@ -2573,7 +2589,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && @@ -2595,7 +2610,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var isArray = Array.isArray; function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2648,15 +2662,14 @@ function coerceRef(returnFiber, current, element) { return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if ("textarea" !== returnFiber.type) - throw ((returnFiber = Object.prototype.toString.call(newChild)), - Error( - "Objects are not valid as a React child (found: " + - ("[object Object]" === returnFiber - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : returnFiber) + - "). If you meant to render a collection of children, use an array instead." - )); + returnFiber = Object.prototype.toString.call(newChild); + throw Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === returnFiber + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : returnFiber) + + "). If you meant to render a collection of children, use an array instead." + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { @@ -2818,7 +2831,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (newChild = createFiberFromFragment( newChild, @@ -2850,7 +2863,7 @@ function ChildReconciler(shouldTrackSideEffects) { ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key ? null : updateFragment(returnFiber, oldFiber, newChild, lanes, null); @@ -2889,7 +2902,7 @@ function ChildReconciler(shouldTrackSideEffects) { updatePortal(returnFiber, existingChildren, newChild, lanes) ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (existingChildren = existingChildren.get(newIdx) || null), updateFragment(returnFiber, existingChildren, newChild, lanes, null) @@ -3072,20 +3085,19 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.type === REACT_FRAGMENT_TYPE && null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); - var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) + if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; + var key = newChild.key; for ( isUnkeyedTopLevelFragment = currentFirstChild; null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - isObject = newChild.type; - if (isObject === REACT_FRAGMENT_TYPE) { + if (isUnkeyedTopLevelFragment.key === key) { + key = newChild.type; + if (key === REACT_FRAGMENT_TYPE) { if (7 === isUnkeyedTopLevelFragment.tag) { deleteRemainingChildren( returnFiber, @@ -3099,7 +3111,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; break a; } - } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + } else if (isUnkeyedTopLevelFragment.elementType === key) { deleteRemainingChildren( returnFiber, isUnkeyedTopLevelFragment.sibling @@ -3191,6 +3203,22 @@ function ChildReconciler(shouldTrackSideEffects) { } return placeSingleChild(returnFiber); } + if (isArrayImpl(newChild)) + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + if (getIteratorFn(newChild)) + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + throwOnInvalidObjectType(returnFiber, newChild); + } if ("string" === typeof newChild || "number" === typeof newChild) return ( (newChild = "" + newChild), @@ -3209,21 +3237,6 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); - if (isArray(newChild)) - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - if (getIteratorFn(newChild)) - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - isObject && throwOnInvalidObjectType(returnFiber, newChild); if ("undefined" === typeof newChild && !isUnkeyedTopLevelFragment) switch (returnFiber.tag) { case 1: @@ -3688,7 +3701,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(263168, 4, create, deps); + return mountEffectImpl(1049600, 4, create, deps); } function updateEffect(create, deps) { return updateEffectImpl(1024, 4, create, deps); @@ -3923,7 +3936,7 @@ var ContextOnlyDispatcher = { isPending = _mountState2[0]; _mountState2 = startTransition.bind(null, _mountState2[1]); mountWorkInProgressHook().memoizedState = _mountState2; - return [_mountState2, isPending]; + return [isPending, _mountState2]; }, useMutableSource: function(source, getSnapshot, subscribe) { var hook = mountWorkInProgressHook(); @@ -3972,8 +3985,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = updateReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4014,8 +4028,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = rerenderReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4184,7 +4199,6 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - markSpawnedWork(1073741824), (workInProgress.lanes = workInProgress.childLanes = 1073741824), (workInProgress.memoizedState = { baseLanes: current, @@ -4558,7 +4572,6 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { )), (workInProgress.memoizedState = SUSPENDED_MARKER), (workInProgress.lanes = 4194304), - markSpawnedWork(4194304), current ); renderLanes = createFiberFromOffscreen( @@ -4712,7 +4725,7 @@ function updateSuspenseFallbackChildren( (primaryChildren.treeBaseDuration = current.treeBaseDuration)), (workInProgress.deletions = null)) : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 262144)); + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); null !== currentFallbackChildFragment ? (fallbackChildren = createWorkInProgress( currentFallbackChildFragment, @@ -5073,14 +5086,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$63 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), + for (var lastTailNode$65 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$65 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$63 + null === lastTailNode$65 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$63.sibling = null); + : (lastTailNode$65.sibling = null); } } function bubbleProperties(completedWork) { @@ -5092,53 +5105,53 @@ function bubbleProperties(completedWork) { if (didBailout) if (0 !== (completedWork.mode & 2)) { for ( - var treeBaseDuration$65 = completedWork.selfBaseDuration, - child$66 = completedWork.child; - null !== child$66; + var treeBaseDuration$67 = completedWork.selfBaseDuration, + child$68 = completedWork.child; + null !== child$68; ) - (newChildLanes |= child$66.lanes | child$66.childLanes), - (subtreeFlags |= child$66.subtreeFlags & 262144), - (subtreeFlags |= child$66.flags & 262144), - (treeBaseDuration$65 += child$66.treeBaseDuration), - (child$66 = child$66.sibling); - completedWork.treeBaseDuration = treeBaseDuration$65; + (newChildLanes |= child$68.lanes | child$68.childLanes), + (subtreeFlags |= child$68.subtreeFlags & 1835008), + (subtreeFlags |= child$68.flags & 1835008), + (treeBaseDuration$67 += child$68.treeBaseDuration), + (child$68 = child$68.sibling); + completedWork.treeBaseDuration = treeBaseDuration$67; } else for ( - treeBaseDuration$65 = completedWork.child; - null !== treeBaseDuration$65; + treeBaseDuration$67 = completedWork.child; + null !== treeBaseDuration$67; ) (newChildLanes |= - treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), - (subtreeFlags |= treeBaseDuration$65.subtreeFlags & 262144), - (subtreeFlags |= treeBaseDuration$65.flags & 262144), - (treeBaseDuration$65.return = completedWork), - (treeBaseDuration$65 = treeBaseDuration$65.sibling); + treeBaseDuration$67.lanes | treeBaseDuration$67.childLanes), + (subtreeFlags |= treeBaseDuration$67.subtreeFlags & 1835008), + (subtreeFlags |= treeBaseDuration$67.flags & 1835008), + (treeBaseDuration$67.return = completedWork), + (treeBaseDuration$67 = treeBaseDuration$67.sibling); else if (0 !== (completedWork.mode & 2)) { - treeBaseDuration$65 = completedWork.actualDuration; - child$66 = completedWork.selfBaseDuration; + treeBaseDuration$67 = completedWork.actualDuration; + child$68 = completedWork.selfBaseDuration; for (var child = completedWork.child; null !== child; ) (newChildLanes |= child.lanes | child.childLanes), (subtreeFlags |= child.subtreeFlags), (subtreeFlags |= child.flags), - (treeBaseDuration$65 += child.actualDuration), - (child$66 += child.treeBaseDuration), + (treeBaseDuration$67 += child.actualDuration), + (child$68 += child.treeBaseDuration), (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$65; - completedWork.treeBaseDuration = child$66; + completedWork.actualDuration = treeBaseDuration$67; + completedWork.treeBaseDuration = child$68; } else for ( - treeBaseDuration$65 = completedWork.child; - null !== treeBaseDuration$65; + treeBaseDuration$67 = completedWork.child; + null !== treeBaseDuration$67; ) (newChildLanes |= - treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), - (subtreeFlags |= treeBaseDuration$65.subtreeFlags), - (subtreeFlags |= treeBaseDuration$65.flags), - (treeBaseDuration$65.return = completedWork), - (treeBaseDuration$65 = treeBaseDuration$65.sibling); + treeBaseDuration$67.lanes | treeBaseDuration$67.childLanes), + (subtreeFlags |= treeBaseDuration$67.subtreeFlags), + (subtreeFlags |= treeBaseDuration$67.flags), + (treeBaseDuration$67.return = completedWork), + (treeBaseDuration$67 = treeBaseDuration$67.sibling); completedWork.subtreeFlags |= subtreeFlags; completedWork.childLanes = newChildLanes; return didBailout; @@ -5345,7 +5358,7 @@ function completeWork(current, workInProgress, renderLanes) { for (newProps = workInProgress.child; null !== newProps; ) (renderLanes = newProps), (updatePayload = current), - (renderLanes.flags &= 262146), + (renderLanes.flags &= 1835010), (type = renderLanes.alternate), null === type ? ((renderLanes.childLanes = 0), @@ -5392,8 +5405,7 @@ function completeWork(current, workInProgress, renderLanes) { ((workInProgress.flags |= 128), (newProps = !0), cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304), - markSpawnedWork(4194304)); + (workInProgress.lanes = 4194304)); } else { if (!newProps) @@ -5420,8 +5432,7 @@ function completeWork(current, workInProgress, renderLanes) { ((workInProgress.flags |= 128), (newProps = !0), cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304), - markSpawnedWork(4194304)); + (workInProgress.lanes = 4194304)); type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) @@ -5729,8 +5740,8 @@ function commitHookEffectListMount(tag, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & tag) === tag) { - var create$84 = effect.create; - effect.destroy = create$84(); + var create$86 = effect.create; + effect.destroy = create$86(); } effect = effect.next; } while (effect !== finishedWork); @@ -5797,10 +5808,7 @@ function attachSuspenseRetryListeners(finishedWork) { wakeables.forEach(function(wakeable) { var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); retryCache.has(wakeable) || - (!0 !== wakeable.__reactDoNotTraceInteractions && - (retry = tracing.unstable_wrap(retry)), - retryCache.add(wakeable), - wakeable.then(retry, retry)); + (retryCache.add(wakeable), wakeable.then(retry, retry)); }); } } @@ -5943,36 +5951,35 @@ function commitMutationEffects(root, firstChild) { } } } -function commitLayoutEffects(finishedWork, root) { +function commitLayoutEffects(finishedWork) { for (nextEffect = finishedWork; null !== nextEffect; ) { var fiber = nextEffect, firstChild = fiber.child; if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) (firstChild.return = fiber), (nextEffect = firstChild); else - for (fiber = finishedWork, firstChild = root; null !== nextEffect; ) { - var fiber$jscomp$0 = nextEffect; - if (0 !== (fiber$jscomp$0.flags & 324)) { - var current = fiber$jscomp$0.alternate; + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; try { - var finishedRoot = firstChild; - if (0 !== (fiber$jscomp$0.flags & 68)) - switch (fiber$jscomp$0.tag) { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { case 0: case 11: case 15: - commitHookEffectListMount(3, fiber$jscomp$0); + commitHookEffectListMount(3, firstChild); break; case 1: - var instance = fiber$jscomp$0.stateNode; - if (fiber$jscomp$0.flags & 4) + var instance = firstChild.stateNode; + if (firstChild.flags & 4) if (null === current) instance.componentDidMount(); else { var prevProps = - fiber$jscomp$0.elementType === fiber$jscomp$0.type + firstChild.elementType === firstChild.type ? current.memoizedProps : resolveDefaultProps( - fiber$jscomp$0.type, + firstChild.type, current.memoizedProps ); instance.componentDidUpdate( @@ -5981,50 +5988,44 @@ function commitLayoutEffects(finishedWork, root) { instance.__reactInternalSnapshotBeforeUpdate ); } - var updateQueue = fiber$jscomp$0.updateQueue; + var updateQueue = firstChild.updateQueue; null !== updateQueue && - commitUpdateQueue(fiber$jscomp$0, updateQueue, instance); + commitUpdateQueue(firstChild, updateQueue, instance); break; case 3: - var updateQueue$85 = fiber$jscomp$0.updateQueue; - if (null !== updateQueue$85) { - finishedRoot = null; - if (null !== fiber$jscomp$0.child) - switch (fiber$jscomp$0.child.tag) { + var updateQueue$87 = firstChild.updateQueue; + if (null !== updateQueue$87) { + var instance$88 = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { case 5: - finishedRoot = - fiber$jscomp$0.child.stateNode.canonical; + instance$88 = firstChild.child.stateNode.canonical; break; case 1: - finishedRoot = fiber$jscomp$0.child.stateNode; + instance$88 = firstChild.child.stateNode; } - commitUpdateQueue( - fiber$jscomp$0, - updateQueue$85, - finishedRoot - ); + commitUpdateQueue(firstChild, updateQueue$87, instance$88); } break; case 5: - null === current && fiber$jscomp$0.flags & 4 && shim(); + null === current && firstChild.flags & 4 && shim(); break; case 6: break; case 4: break; case 12: - var onRender = fiber$jscomp$0.memoizedProps.onRender, - commitTime$88 = commitTime; + var onRender = firstChild.memoizedProps.onRender; + instance$88 = commitTime; current = null === current ? "mount" : "update"; "function" === typeof onRender && onRender( - fiber$jscomp$0.memoizedProps.id, + firstChild.memoizedProps.id, current, - fiber$jscomp$0.actualDuration, - fiber$jscomp$0.treeBaseDuration, - fiber$jscomp$0.actualStartTime, - commitTime$88, - finishedRoot.memoizedInteractions + firstChild.actualDuration, + firstChild.treeBaseDuration, + firstChild.actualStartTime, + instance$88 ); break; case 13: @@ -6040,48 +6041,45 @@ function commitLayoutEffects(finishedWork, root) { "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." ); } - if (fiber$jscomp$0.flags & 256) { - finishedRoot = void 0; - var ref = fiber$jscomp$0.ref; + if (firstChild.flags & 256) { + instance$88 = void 0; + var ref = firstChild.ref; if (null !== ref) { - var instance$jscomp$0 = fiber$jscomp$0.stateNode; - switch (fiber$jscomp$0.tag) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { case 5: - finishedRoot = instance$jscomp$0.canonical; + instance$88 = instance$jscomp$0.canonical; break; default: - finishedRoot = instance$jscomp$0; + instance$88 = instance$jscomp$0; } "function" === typeof ref - ? ref(finishedRoot) - : (ref.current = finishedRoot); + ? ref(instance$88) + : (ref.current = instance$88); } } } catch (error) { - captureCommitPhaseError( - fiber$jscomp$0, - fiber$jscomp$0.return, - error - ); + captureCommitPhaseError(firstChild, firstChild.return, error); } } - if (fiber$jscomp$0 === fiber) { + if (firstChild === fiber) { nextEffect = null; break; } - finishedRoot = fiber$jscomp$0.sibling; - if (null !== finishedRoot) { - finishedRoot.return = fiber$jscomp$0.return; - nextEffect = finishedRoot; + instance$88 = firstChild.sibling; + if (null !== instance$88) { + instance$88.return = firstChild.return; + nextEffect = instance$88; break; } - nextEffect = fiber$jscomp$0.return; + nextEffect = firstChild.return; } } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -6103,7 +6101,6 @@ var ceil = Math.ceil, pendingPassiveEffectsLanes = 0, nestedUpdateCount = 0, rootWithNestedUpdates = null, - spawnedWorkDuringRender = null, currentEventTime = -1, currentEventTransitionLane = 0; function requestEventTime() { @@ -6143,15 +6140,13 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { markRootSuspended$1(root, workInProgressRootRenderLanes)); 1 === lane ? 0 !== (executionContext & 4) && 0 === (executionContext & 24) - ? (schedulePendingInteractions(root, lane), performSyncWorkOnRoot(root)) + ? performSyncWorkOnRoot(root) : (ensureRootIsScheduled(root, eventTime), - schedulePendingInteractions(root, lane), 0 === executionContext && 0 === (fiber.mode & 1) && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue())) - : (ensureRootIsScheduled(root, eventTime), - schedulePendingInteractions(root, lane)); + includesLegacySyncCallbacks && flushSyncCallbacks())) + : ensureRootIsScheduled(root, eventTime); return root; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { @@ -6173,8 +6168,7 @@ function ensureRootIsScheduled(root, currentTime) { suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes, expirationTimes = root.expirationTimes, - lanes = root.pendingLanes, - expiredLanes = 0; + lanes = root.pendingLanes; 0 < lanes; ) { @@ -6184,10 +6178,9 @@ function ensureRootIsScheduled(root, currentTime) { if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) expirationTimes[index$5] = computeExpirationTime(lane, currentTime); - } else expirationTime <= currentTime && (expiredLanes |= lane); + } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } - 0 !== expiredLanes && markRootExpired(root, expiredLanes); suspendedLanes = getNextLanes( root, root === workInProgressRoot ? workInProgressRootRenderLanes : 0 @@ -6202,11 +6195,17 @@ function ensureRootIsScheduled(root, currentTime) { ) { null != existingCallbackNode && cancelCallback(existingCallbackNode); if (1 === currentTime) - (existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? (syncQueue = [existingCallbackNode]) - : syncQueue.push(existingCallbackNode), - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue), + 0 === root.tag + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + (includesLegacySyncCallbacks = !0), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)) + : ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), (existingCallbackNode = null); else { switch (lanesToEventPriority(suspendedLanes)) { @@ -6247,45 +6246,48 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - if (didTimeout) - return ( - markRootExpired(root, lanes), ensureRootIsScheduled(root, now()), null - ); - var lanes$jscomp$0 = lanes; - didTimeout = executionContext; - executionContext |= 8; - var prevDispatcher = pushDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== lanes$jscomp$0 - ) - (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, lanes$jscomp$0), - startWorkOnPendingInteractions(root, lanes$jscomp$0); - lanes$jscomp$0 = pushInteractions(root); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = lanes$jscomp$0; - ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = didTimeout; - null !== workInProgress - ? (didTimeout = 0) - : ((workInProgressRoot = null), - (workInProgressRootRenderLanes = 0), - (didTimeout = workInProgressRootExitStatus)); + var JSCompiler_inline_result = + 0 !== (lanes & root.expiredLanes) + ? !1 + : 0 !== (root.current.mode & 32) + ? !0 + : 0 === (lanes & 30); + if (JSCompiler_inline_result && !didTimeout) { + didTimeout = lanes; + JSCompiler_inline_result = executionContext; + executionContext |= 8; + var prevDispatcher = pushDispatcher(); + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== didTimeout + ) + (workInProgressRootRenderTargetTime = now() + 500), + prepareFreshStack(root, didTimeout); + do + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + ReactCurrentDispatcher$2.current = prevDispatcher; + executionContext = JSCompiler_inline_result; + null !== workInProgress + ? (didTimeout = 0) + : ((workInProgressRoot = null), + (workInProgressRootRenderLanes = 0), + (didTimeout = workInProgressRootExitStatus)); + } else didTimeout = renderRootSync(root, lanes); if (0 !== didTimeout) { 2 === didTimeout && ((executionContext |= 32), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + (JSCompiler_inline_result = getLanesToRetrySynchronouslyOnError(root)), + 0 !== JSCompiler_inline_result && + ((lanes = JSCompiler_inline_result), + (didTimeout = renderRootSync(root, JSCompiler_inline_result)))); if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6309,10 +6311,10 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; - prevDispatcher = root.suspendedLanes; - if ((prevDispatcher & lanes) !== lanes) { + JSCompiler_inline_result = root.suspendedLanes; + if ((JSCompiler_inline_result & lanes) !== lanes) { requestEventTime(); - root.pingedLanes |= root.suspendedLanes & prevDispatcher; + root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result; break; } root.timeoutHandle = scheduleTimeout( @@ -6327,14 +6329,15 @@ function performConcurrentWorkOnRoot(root, didTimeout) { markRootSuspended$1(root, lanes); if ((lanes & 4194240) === lanes) break; didTimeout = root.eventTimes; - for (prevDispatcher = -1; 0 < lanes; ) { + for (JSCompiler_inline_result = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); - lanes$jscomp$0 = 1 << index$4; + prevDispatcher = 1 << index$4; index$4 = didTimeout[index$4]; - index$4 > prevDispatcher && (prevDispatcher = index$4); - lanes &= ~lanes$jscomp$0; + index$4 > JSCompiler_inline_result && + (JSCompiler_inline_result = index$4); + lanes &= ~prevDispatcher; } - lanes = prevDispatcher; + lanes = JSCompiler_inline_result; lanes = now() - lanes; lanes = (120 > lanes @@ -6387,17 +6390,16 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 24)) throw Error("Should not already be working."); flushPassiveEffects(); - var lanes; - if ((lanes = root === workInProgressRoot)) - lanes = 0 !== (root.entanglements[0] & workInProgressRootRenderLanes); - lanes = lanes ? workInProgressRootRenderLanes : getNextLanes(root, 0); + var lanes = getNextLanes(root, 0); + if (0 === (lanes & 1)) return ensureRootIsScheduled(root, now()), null; var exitStatus = renderRootSync(root, lanes); - 0 !== root.tag && - 2 === exitStatus && - ((executionContext |= 32), - root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + if (0 !== root.tag && 2 === exitStatus) { + executionContext |= 32; + root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + 0 !== errorRetryLanes && + ((lanes = errorRetryLanes), (exitStatus = renderRootSync(root, lanes))); + } if (1 === exitStatus) throw ((exitStatus = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6482,7 +6484,6 @@ function prepareFreshStack(root, lanes) { } interleavedQueues = null; } - spawnedWorkDuringRender = null; } function handleError(root$jscomp$0, thrownValue) { do { @@ -6542,15 +6543,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$79 = returnFiber; + workInProgress$81 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$79.tag)) { - var nextState = workInProgress$79.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$81.tag)) { + var nextState = workInProgress$81.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$79.memoizedProps; + var props = workInProgress$81.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6562,17 +6563,17 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$79.updateQueue; + var wakeables = workInProgress$81.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$79.updateQueue = updateQueue; + workInProgress$81.updateQueue = updateQueue; } else wakeables.add(wakeable); if ( - 0 === (workInProgress$79.mode & 1) && - workInProgress$79 !== returnFiber + 0 === (workInProgress$81.mode & 1) && + workInProgress$81 !== returnFiber ) { - workInProgress$79.flags |= 128; + workInProgress$81.flags |= 128; sourceFiber.flags |= 32768; sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) @@ -6605,12 +6606,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$79.flags |= 16384; - workInProgress$79.lanes = thrownValue; + workInProgress$81.flags |= 16384; + workInProgress$81.lanes = thrownValue; break a; } - workInProgress$79 = workInProgress$79.return; - } while (null !== workInProgress$79); + workInProgress$81 = workInProgress$81.return; + } while (null !== workInProgress$81); value = Error( (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6619,47 +6620,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$79 = returnFiber; + workInProgress$81 = returnFiber; do { - switch (workInProgress$79.tag) { + switch (workInProgress$81.tag) { case 3: root = value; - workInProgress$79.flags |= 16384; + workInProgress$81.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$79.lanes |= thrownValue; - var update$80 = createRootErrorUpdate( - workInProgress$79, + workInProgress$81.lanes |= thrownValue; + var update$82 = createRootErrorUpdate( + workInProgress$81, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$79, update$80); + enqueueCapturedUpdate(workInProgress$81, update$82); break a; case 1: root = value; - var ctor = workInProgress$79.type, - instance = workInProgress$79.stateNode; + var ctor = workInProgress$81.type, + instance = workInProgress$81.stateNode; if ( - 0 === (workInProgress$79.flags & 128) && + 0 === (workInProgress$81.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$79.flags |= 16384; + workInProgress$81.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$79.lanes |= thrownValue; - var update$83 = createClassErrorUpdate( - workInProgress$79, + workInProgress$81.lanes |= thrownValue; + var update$85 = createClassErrorUpdate( + workInProgress$81, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$79, update$83); + enqueueCapturedUpdate(workInProgress$81, update$85); break a; } } - workInProgress$79 = workInProgress$79.return; - } while (null !== workInProgress$79); + workInProgress$81 = workInProgress$81.return; + } while (null !== workInProgress$81); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6677,18 +6678,12 @@ function pushDispatcher() { ReactCurrentDispatcher$2.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } -function pushInteractions(root) { - var prevInteractions = tracing.__interactionsRef.current; - tracing.__interactionsRef.current = root.memoizedInteractions; - return prevInteractions; -} function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 8; var prevDispatcher = pushDispatcher(); - if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) - prepareFreshStack(root, lanes), startWorkOnPendingInteractions(root, lanes); - lanes = pushInteractions(root); + (workInProgressRoot === root && workInProgressRootRenderLanes === lanes) || + prepareFreshStack(root, lanes); do try { workLoopSync(); @@ -6698,7 +6693,6 @@ function renderRootSync(root, lanes) { } while (1); resetContextDependencies(); - tracing.__interactionsRef.current = lanes; executionContext = prevExecutionContext; ReactCurrentDispatcher$2.current = prevDispatcher; if (null !== workInProgress) @@ -6778,12 +6772,15 @@ function completeUnitOfWork(unitOfWork) { 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } function commitRoot(root) { - var previousUpdateLanePriority = currentUpdatePriority; + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig$2.transition; try { - (currentUpdatePriority = 1), + (ReactCurrentBatchConfig$2.transition = 0), + (currentUpdatePriority = 1), commitRootImpl(root, previousUpdateLanePriority); } finally { - currentUpdatePriority = previousUpdateLanePriority; + (ReactCurrentBatchConfig$2.transition = prevTransition), + (currentUpdatePriority = previousUpdateLanePriority); } return null; } @@ -6818,11 +6815,12 @@ function commitRootImpl(root, renderPriorityLevel) { })); remainingLanes = 0 !== (finishedWork.flags & 8054); if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { - remainingLanes = currentUpdatePriority; + remainingLanes = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = currentUpdatePriority; currentUpdatePriority = 1; var prevExecutionContext = executionContext; executionContext |= 16; - var prevInteractions = pushInteractions(root); ReactCurrentOwner$2.current = null; commitBeforeMutationEffects(root, finishedWork); commitTime = now$1(); @@ -6830,29 +6828,16 @@ function commitRootImpl(root, renderPriorityLevel) { root.current = finishedWork; commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - tracing.__interactionsRef.current = prevInteractions; executionContext = prevExecutionContext; - currentUpdatePriority = remainingLanes; + currentUpdatePriority = previousPriority; + ReactCurrentBatchConfig$2.transition = remainingLanes; } else (root.current = finishedWork), (commitTime = now$1()); - if ((prevExecutionContext = rootDoesHavePassiveEffects)) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; - if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) { - prevInteractions = spawnedWorkDuringRender; - spawnedWorkDuringRender = null; - for (var i = 0; i < prevInteractions.length; i++) - scheduleInteractions( - root, - prevInteractions[i], - root.memoizedInteractions - ); - } - schedulePendingInteractions(root, remainingLanes); - } else legacyErrorBoundariesThatAlreadyFailed = null; - prevExecutionContext || finishPendingInteractions(root, lanes); + 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ @@ -6866,28 +6851,31 @@ function commitRootImpl(root, renderPriorityLevel) { (firstUncaughtError = null), root); if (0 !== (executionContext & 4)) return null; - flushSyncCallbackQueue(); + 0 !== (pendingPassiveEffectsLanes & 1) && + 0 !== root.tag && + flushPassiveEffects(); + flushSyncCallbacks(); return null; } function flushPassiveEffects() { - if (0 !== pendingPassiveEffectsLanes) { - var b = lanesToEventPriority(pendingPassiveEffectsLanes), + if (null !== rootWithPendingPassiveEffects) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), + prevTransition = ReactCurrentBatchConfig$2.transition, previousPriority = currentUpdatePriority; try { - currentUpdatePriority = 16 < b ? 16 : b; + ReactCurrentBatchConfig$2.transition = 0; + currentUpdatePriority = 16 > renderPriority ? 16 : renderPriority; if (null === rootWithPendingPassiveEffects) var JSCompiler_inline_result = !1; else { - b = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; + renderPriority = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; pendingPassiveEffectsLanes = 0; if (0 !== (executionContext & 24)) throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 16; - var prevInteractions = pushInteractions(b); - for (nextEffect = b.current; null !== nextEffect; ) { + for (nextEffect = renderPriority.current; null !== nextEffect; ) { var fiber = nextEffect, child = fiber.child; if (0 !== (nextEffect.flags & 16)) { @@ -6962,7 +6950,7 @@ function flushPassiveEffects() { nextEffect = fiber.return; } } - var finishedWork = b.current; + var finishedWork = renderPriority.current; for (nextEffect = finishedWork; null !== nextEffect; ) { child = nextEffect; var firstChild = child.child; @@ -6995,15 +6983,21 @@ function flushPassiveEffects() { nextEffect = deletions.return; } } - tracing.__interactionsRef.current = prevInteractions; - finishPendingInteractions(b, lanes); executionContext = prevExecutionContext; - flushSyncCallbackQueue(); + flushSyncCallbacks(); + if ( + injectedHook && + "function" === typeof injectedHook.onPostCommitFiberRoot + ) + try { + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); + } catch (err) {} JSCompiler_inline_result = !0; } return JSCompiler_inline_result; } finally { - currentUpdatePriority = previousPriority; + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$2.transition = prevTransition); } } return !1; @@ -7016,8 +7010,7 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { rootFiber = markUpdateLaneFromFiberToRoot(rootFiber, 1); null !== rootFiber && (markRootUpdated(rootFiber, 1, sourceFiber), - ensureRootIsScheduled(rootFiber, sourceFiber), - schedulePendingInteractions(rootFiber, 1)); + ensureRootIsScheduled(rootFiber, sourceFiber)); } function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) @@ -7058,8 +7051,7 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { ); null !== nearestMountedAncestor && (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), - ensureRootIsScheduled(nearestMountedAncestor, sourceFiber), - schedulePendingInteractions(nearestMountedAncestor, 1)); + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } @@ -7081,7 +7073,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { ? prepareFreshStack(root, 0) : (workInProgressRootPingedLanes |= pingedLanes)); ensureRootIsScheduled(root, wakeable); - schedulePendingInteractions(root, pingedLanes); } function resolveRetryWakeable(boundaryFiber, wakeable) { var retryCache = boundaryFiber.stateNode; @@ -7097,8 +7088,7 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && (markRootUpdated(boundaryFiber, wakeable, retryCache), - ensureRootIsScheduled(boundaryFiber, retryCache), - schedulePendingInteractions(boundaryFiber, wakeable)); + ensureRootIsScheduled(boundaryFiber, retryCache)); } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { @@ -7230,14 +7220,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? nextValue.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; - "function" === typeof getDerivedStateFromProps && - applyDerivedStateFromProps( - workInProgress, - updateLanes, - getDerivedStateFromProps, - current - ); nextValue.updater = classComponentUpdater; workInProgress.stateNode = nextValue; nextValue._reactInternals = workInProgress; @@ -7453,11 +7435,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateLanes = workInProgress.type._context; nextValue = workInProgress.pendingProps; hasContext = workInProgress.memoizedProps; - getDerivedStateFromProps = nextValue.value; + var newValue = nextValue.value; push(valueCursor, updateLanes._currentValue2); - updateLanes._currentValue2 = getDerivedStateFromProps; + updateLanes._currentValue2 = newValue; if (null !== hasContext) - if (objectIs(hasContext.value, getDerivedStateFromProps)) { + if (objectIs(hasContext.value, newValue)) { if ( hasContext.children === nextValue.children && !didPerformWorkStackCursor.current @@ -7471,25 +7453,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - getDerivedStateFromProps = workInProgress.child, - null !== getDerivedStateFromProps && - (getDerivedStateFromProps.return = workInProgress); - null !== getDerivedStateFromProps; + newValue = workInProgress.child, + null !== newValue && (newValue.return = workInProgress); + null !== newValue; ) { - var list = getDerivedStateFromProps.dependencies; + var list = newValue.dependencies; if (null !== list) { - hasContext = getDerivedStateFromProps.child; + hasContext = newValue.child; for ( var dependency = list.firstContext; null !== dependency; ) { if (dependency.context === updateLanes) { - if (1 === getDerivedStateFromProps.tag) { + if (1 === newValue.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; - var updateQueue = getDerivedStateFromProps.updateQueue; + var updateQueue = newValue.updateQueue; if (null !== updateQueue) { updateQueue = updateQueue.shared; var pending = updateQueue.pending; @@ -7500,13 +7481,10 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateQueue.pending = dependency; } } - getDerivedStateFromProps.lanes |= renderLanes; - dependency = getDerivedStateFromProps.alternate; + newValue.lanes |= renderLanes; + dependency = newValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - getDerivedStateFromProps.return, - renderLanes - ); + scheduleWorkOnParentPath(newValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7514,32 +7492,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else hasContext = - 10 === getDerivedStateFromProps.tag - ? getDerivedStateFromProps.type === workInProgress.type + 10 === newValue.tag + ? newValue.type === workInProgress.type ? null - : getDerivedStateFromProps.child - : getDerivedStateFromProps.child; - if (null !== hasContext) - hasContext.return = getDerivedStateFromProps; + : newValue.child + : newValue.child; + if (null !== hasContext) hasContext.return = newValue; else - for ( - hasContext = getDerivedStateFromProps; - null !== hasContext; - - ) { + for (hasContext = newValue; null !== hasContext; ) { if (hasContext === workInProgress) { hasContext = null; break; } - getDerivedStateFromProps = hasContext.sibling; - if (null !== getDerivedStateFromProps) { - getDerivedStateFromProps.return = hasContext.return; - hasContext = getDerivedStateFromProps; + newValue = hasContext.sibling; + if (null !== newValue) { + newValue.return = hasContext.return; + hasContext = newValue; break; } hasContext = hasContext.return; } - getDerivedStateFromProps = hasContext; + newValue = hasContext; } reconcileChildren( current, @@ -7628,93 +7601,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { "). This error is likely caused by a bug in React. Please file an issue." ); }; -function markSpawnedWork(lane) { - null === spawnedWorkDuringRender - ? (spawnedWorkDuringRender = [lane]) - : spawnedWorkDuringRender.push(lane); -} -function scheduleInteractions(root, lane, interactions) { - if (0 < interactions.size) { - var pendingInteractionMap = root.pendingInteractionMap, - pendingInteractions = pendingInteractionMap.get(lane); - null != pendingInteractions - ? interactions.forEach(function(interaction) { - pendingInteractions.has(interaction) || interaction.__count++; - pendingInteractions.add(interaction); - }) - : (pendingInteractionMap.set(lane, new Set(interactions)), - interactions.forEach(function(interaction) { - interaction.__count++; - })); - pendingInteractionMap = tracing.__subscriberRef.current; - if (null !== pendingInteractionMap) - pendingInteractionMap.onWorkScheduled( - interactions, - 1e3 * lane + root.interactionThreadID - ); - } -} -function schedulePendingInteractions(root, lane) { - scheduleInteractions(root, lane, tracing.__interactionsRef.current); -} -function startWorkOnPendingInteractions(root, lanes) { - var interactions = new Set(); - root.pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledLane - ) { - 0 !== (lanes & scheduledLane) && - scheduledInteractions.forEach(function(interaction) { - return interactions.add(interaction); - }); - }); - root.memoizedInteractions = interactions; - if (0 < interactions.size) { - var subscriber = tracing.__subscriberRef.current; - if (null !== subscriber) { - root = 1e3 * lanes + root.interactionThreadID; - try { - subscriber.onWorkStarted(interactions, root); - } catch (error) { - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } - } - } -} -function finishPendingInteractions(root, committedLanes) { - var remainingLanesAfterCommit = root.pendingLanes; - try { - var subscriber = tracing.__subscriberRef.current; - if (null !== subscriber && 0 < root.memoizedInteractions.size) - subscriber.onWorkStopped( - root.memoizedInteractions, - 1e3 * committedLanes + root.interactionThreadID - ); - } catch (error) { - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } finally { - var pendingInteractionMap = root.pendingInteractionMap; - pendingInteractionMap.forEach(function(scheduledInteractions, lane) { - 0 === (remainingLanesAfterCommit & lane) && - (pendingInteractionMap.delete(lane), - scheduledInteractions.forEach(function(interaction) { - interaction.__count--; - if (null !== subscriber && 0 === interaction.__count) - try { - subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$95) { - scheduleCallback(ImmediatePriority, function() { - throw error$95; - }); - } - })); - }); - } -} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -7770,7 +7656,7 @@ function createWorkInProgress(current, pendingProps) { (workInProgress.deletions = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); - workInProgress.flags = current.flags & 262144; + workInProgress.flags = current.flags & 1835008; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7811,10 +7697,7 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - 1 <= - (null == pendingProps.unstable_level - ? 1 - : pendingProps.unstable_level) && (mode |= 8); + mode |= 24; break; case REACT_PROFILER_TYPE: return ( @@ -7921,11 +7804,8 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.callbackPriority = 0; this.eventTimes = createLaneMap(0); this.expirationTimes = createLaneMap(-1); - this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; + this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.expiredLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; this.entanglements = createLaneMap(0); - this.interactionThreadID = tracing.unstable_getThreadID(); - this.memoizedInteractions = new Set(); - this.pendingInteractionMap = new Map(); } function createPortal(children, containerInfo, implementation) { var key = @@ -8036,14 +7916,14 @@ batchedUpdatesImpl = function(fn, a) { (executionContext = prevExecutionContext), 0 === executionContext && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue()); + includesLegacySyncCallbacks && flushSyncCallbacks()); } }; var roots = new Map(), - devToolsConfig$jscomp$inline_968 = { + devToolsConfig$jscomp$inline_966 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.3", + version: "17.0.3-2d8d133e1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8058,11 +7938,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1212 = { - bundleType: devToolsConfig$jscomp$inline_968.bundleType, - version: devToolsConfig$jscomp$inline_968.version, - rendererPackageName: devToolsConfig$jscomp$inline_968.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_968.rendererConfig, +var internals$jscomp$inline_1208 = { + bundleType: devToolsConfig$jscomp$inline_966.bundleType, + version: devToolsConfig$jscomp$inline_966.version, + rendererPackageName: devToolsConfig$jscomp$inline_966.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_966.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8077,25 +7957,26 @@ var internals$jscomp$inline_1212 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_968.findFiberByHostInstance || + devToolsConfig$jscomp$inline_966.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, - getCurrentFiber: null + getCurrentFiber: null, + reconcilerVersion: "17.0.3-2d8d133e1" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1213 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1209 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1213.isDisabled && - hook$jscomp$inline_1213.supportsFiber + !hook$jscomp$inline_1209.isDisabled && + hook$jscomp$inline_1209.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1213.inject( - internals$jscomp$inline_1212 + (rendererID = hook$jscomp$inline_1209.inject( + internals$jscomp$inline_1208 )), - (injectedHook = hook$jscomp$inline_1213); + (injectedHook = hook$jscomp$inline_1209); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -8133,24 +8014,20 @@ exports.findHostInstance_DEPRECATED = function(componentOrHandle) { : componentOrHandle; }; exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { +exports.render = function(element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 2); - JSCompiler_inline_result = createFiber( - 3, - null, - null, - JSCompiler_inline_result - ); - root.current = JSCompiler_inline_result; - JSCompiler_inline_result.stateNode = root; - JSCompiler_inline_result.memoizedState = { element: null }; - initializeUpdateQueue(JSCompiler_inline_result); - roots.set(containerTag, root); - } + root || + ((root = concurrentRoot ? 1 : 0), + (concurrentRoot = new FiberRootNode(containerTag, root, !1)), + (root = 1 === root ? 1 : 0), + isDevToolsPresent && (root |= 2), + (root = createFiber(3, null, null, root)), + (concurrentRoot.current = root), + (root.stateNode = concurrentRoot), + (root.memoizedState = { element: null }), + initializeUpdateQueue(root), + (root = concurrentRoot), + roots.set(containerTag, root)); updateContainer(element, root, null, callback); a: if (((element = root.current), element.child)) switch (element.child.tag) { diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.js b/Libraries/Renderer/implementations/ReactFabric-profiling.js index 65acff0cff3217..ce7c222db6c7b4 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -8,15 +8,14 @@ * @nolint * @providesModule ReactFabric-profiling * @preventMunge - * @generated + * @generated SignedSource<<06caca3d95f98101d397316857fe09c9>> */ "use strict"; require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), - Scheduler = require("scheduler"), - tracing = require("scheduler/tracing"); + Scheduler = require("scheduler"); function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -64,7 +63,8 @@ function invokeGuardedCallbackAndCatchFirstError( hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } } -var getFiberCurrentPropsFromNode = null, +var isArrayImpl = Array.isArray, + getFiberCurrentPropsFromNode = null, getInstanceFromNode = null, getNodeFromInstance = null; function executeDispatch(event, listener, inst) { @@ -76,7 +76,7 @@ function executeDispatch(event, listener, inst) { function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; - if (Array.isArray(dispatchListener)) + if (isArrayImpl(dispatchListener)) throw Error("executeDirectDispatch(...): Invalid `event`."); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) @@ -290,36 +290,46 @@ function recordTouchEnd(touch) { (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } -var ResponderTouchHistoryStore = { - recordTouchTrack: function(topLevelType, nativeEvent) { - if (isMoveish(topLevelType)) - nativeEvent.changedTouches.forEach(recordTouchMove); - else if (isStartish(topLevelType)) - nativeEvent.changedTouches.forEach(recordTouchStart), - (touchHistory.numberActiveTouches = nativeEvent.touches.length), - 1 === touchHistory.numberActiveTouches && - (touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier); - else if ( - "topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType - ) - if ( - (nativeEvent.changedTouches.forEach(recordTouchEnd), - (touchHistory.numberActiveTouches = nativeEvent.touches.length), - 1 === touchHistory.numberActiveTouches) +var instrumentationCallback, + ResponderTouchHistoryStore = { + instrument: function(callback) { + instrumentationCallback = callback; + }, + recordTouchTrack: function(topLevelType, nativeEvent) { + null != instrumentationCallback && + instrumentationCallback(topLevelType, nativeEvent); + if (isMoveish(topLevelType)) + nativeEvent.changedTouches.forEach(recordTouchMove); + else if (isStartish(topLevelType)) + nativeEvent.changedTouches.forEach(recordTouchStart), + (touchHistory.numberActiveTouches = nativeEvent.touches.length), + 1 === touchHistory.numberActiveTouches && + (touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier); + else if ( + "topTouchEnd" === topLevelType || + "topTouchCancel" === topLevelType ) - for (topLevelType = 0; topLevelType < touchBank.length; topLevelType++) - if ( - ((nativeEvent = touchBank[topLevelType]), - null != nativeEvent && nativeEvent.touchActive) - ) { - touchHistory.indexOfSingleActiveTouch = topLevelType; - break; - } - }, - touchHistory: touchHistory -}; + if ( + (nativeEvent.changedTouches.forEach(recordTouchEnd), + (touchHistory.numberActiveTouches = nativeEvent.touches.length), + 1 === touchHistory.numberActiveTouches) + ) + for ( + topLevelType = 0; + topLevelType < touchBank.length; + topLevelType++ + ) + if ( + ((nativeEvent = touchBank[topLevelType]), + null != nativeEvent && nativeEvent.touchActive) + ) { + touchHistory.indexOfSingleActiveTouch = topLevelType; + break; + } + }, + touchHistory: touchHistory + }; function accumulate(current, next) { if (null == next) throw Error( @@ -327,9 +337,9 @@ function accumulate(current, next) { ); return null == current ? next - : Array.isArray(current) + : isArrayImpl(current) ? current.concat(next) - : Array.isArray(next) + : isArrayImpl(next) ? [current].concat(next) : [current, next]; } @@ -339,12 +349,12 @@ function accumulateInto(current, next) { "accumulateInto(...): Accumulated items must not be null or undefined." ); if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; + if (isArrayImpl(current)) { + if (isArrayImpl(next)) return current.push.apply(current, next), current; current.push(next); return current; } - return Array.isArray(next) ? [current].concat(next) : [current, next]; + return isArrayImpl(next) ? [current].concat(next) : [current, next]; } function forEachAccumulated(arr, cb, scope) { Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); @@ -570,7 +580,7 @@ var ResponderEventPlugin = { b: { JSCompiler_temp = shouldSetEventType._dispatchListeners; targetInst = shouldSetEventType._dispatchInstances; - if (Array.isArray(JSCompiler_temp)) + if (isArrayImpl(JSCompiler_temp)) for ( depthA = 0; depthA < JSCompiler_temp.length && @@ -921,7 +931,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_223 = { +var injectedNamesToPlugins$jscomp$inline_221 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -956,34 +966,34 @@ var injectedNamesToPlugins$jscomp$inline_223 = { } } }, - isOrderingDirty$jscomp$inline_224 = !1, - pluginName$jscomp$inline_225; -for (pluginName$jscomp$inline_225 in injectedNamesToPlugins$jscomp$inline_223) + isOrderingDirty$jscomp$inline_222 = !1, + pluginName$jscomp$inline_223; +for (pluginName$jscomp$inline_223 in injectedNamesToPlugins$jscomp$inline_221) if ( - injectedNamesToPlugins$jscomp$inline_223.hasOwnProperty( - pluginName$jscomp$inline_225 + injectedNamesToPlugins$jscomp$inline_221.hasOwnProperty( + pluginName$jscomp$inline_223 ) ) { - var pluginModule$jscomp$inline_226 = - injectedNamesToPlugins$jscomp$inline_223[pluginName$jscomp$inline_225]; + var pluginModule$jscomp$inline_224 = + injectedNamesToPlugins$jscomp$inline_221[pluginName$jscomp$inline_223]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_225) || - namesToPlugins[pluginName$jscomp$inline_225] !== - pluginModule$jscomp$inline_226 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_223) || + namesToPlugins[pluginName$jscomp$inline_223] !== + pluginModule$jscomp$inline_224 ) { - if (namesToPlugins[pluginName$jscomp$inline_225]) + if (namesToPlugins[pluginName$jscomp$inline_223]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_225 + + pluginName$jscomp$inline_223 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_225 - ] = pluginModule$jscomp$inline_226; - isOrderingDirty$jscomp$inline_224 = !0; + pluginName$jscomp$inline_223 + ] = pluginModule$jscomp$inline_224; + isOrderingDirty$jscomp$inline_222 = !0; } } -isOrderingDirty$jscomp$inline_224 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_222 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -998,7 +1008,22 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - null !== to + var fromOrTo = from || to; + (fromOrTo = fromOrTo && fromOrTo.stateNode) && + fromOrTo.canonical._internalInstanceHandle + ? (from && + nativeFabricUIManager.setIsJSResponder( + from.stateNode.node, + !1, + blockNativeResponder || !1 + ), + to && + nativeFabricUIManager.setIsJSResponder( + to.stateNode.node, + !0, + blockNativeResponder || !1 + )) + : null !== to ? ReactNativePrivateInterface.UIManager.setJSResponder( to.stateNode.canonical._nativeTag, blockNativeResponder @@ -1022,7 +1047,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1041,6 +1067,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1050,7 +1077,7 @@ function getIteratorFn(maybeIterable) { maybeIterable["@@iterator"]; return "function" === typeof maybeIterable ? maybeIterable : null; } -function getComponentName(type) { +function getComponentNameFromType(type) { if (null == type) return null; if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; @@ -1067,6 +1094,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1076,22 +1105,83 @@ function getComponentName(type) { return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; - innerType = innerType.displayName || innerType.name || ""; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: return ( - type.displayName || - ("" !== innerType ? "ForwardRef(" + innerType + ")" : "ForwardRef") + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" ); - case REACT_MEMO_TYPE: - return getComponentName(type.type); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; try { - return getComponentName(type(innerType)); + return getComponentNameFromType(type(innerType)); } catch (x) {} } return null; } +function getComponentNameFromFiber(fiber) { + var type = fiber.type; + switch (fiber.tag) { + case 24: + return "Cache"; + case 9: + return (type.displayName || "Context") + ".Consumer"; + case 10: + return (type._context.displayName || "Context") + ".Provider"; + case 18: + return "DehydratedFragment"; + case 11: + return ( + (fiber = type.render), + (fiber = fiber.displayName || fiber.name || ""), + type.displayName || + ("" !== fiber ? "ForwardRef(" + fiber + ")" : "ForwardRef") + ); + case 7: + return "Fragment"; + case 5: + return type; + case 4: + return "Portal"; + case 3: + return "Root"; + case 6: + return "Text"; + case 16: + return getComponentNameFromType(type); + case 23: + return "LegacyHidden"; + case 8: + return type === REACT_STRICT_MODE_TYPE ? "StrictMode" : "Mode"; + case 22: + return "Offscreen"; + case 12: + return "Profiler"; + case 21: + return "Scope"; + case 13: + return "Suspense"; + case 19: + return "SuspenseList"; + case 1: + case 0: + case 17: + case 2: + case 14: + case 15: + if ("function" === typeof type) + return type.displayName || type.name || null; + if ("string" === typeof type) return type; + } + return null; +} function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1100,7 +1190,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1188,19 +1278,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1243,7 +1328,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) + if (isArrayImpl(node)) for (var i = node.length; i-- && 0 < removedKeyCount; ) restoreDeletedValuesInNestedArray( updatePayload, @@ -1289,9 +1374,9 @@ function diffNestedProperty( : prevProp ? clearNestedProperty(updatePayload, prevProp, validAttributes) : updatePayload; - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) + if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { var minLength = prevProp.length < nextProp.length ? prevProp.length : nextProp.length, i; @@ -1316,7 +1401,7 @@ function diffNestedProperty( ); return updatePayload; } - return Array.isArray(prevProp) + return isArrayImpl(prevProp) ? diffProperties( updatePayload, ReactNativePrivateInterface.flattenStyle(prevProp), @@ -1332,7 +1417,7 @@ function diffNestedProperty( } function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) return updatePayload; - if (!Array.isArray(nextProp)) + if (!isArrayImpl(nextProp)) return diffProperties( updatePayload, emptyObject, @@ -1349,7 +1434,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { } function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) return updatePayload; - if (!Array.isArray(prevProp)) + if (!isArrayImpl(prevProp)) return diffProperties( updatePayload, prevProp, @@ -1467,7 +1552,7 @@ function executeDispatchesAndReleaseTopLevel(e) { if (e) { var dispatchListeners = e._dispatchListeners, dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) + if (isArrayImpl(dispatchListeners)) for ( var i = 0; i < dispatchListeners.length && !e.isPropagationStopped(); @@ -1527,6 +1612,241 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } +var scheduleCallback = Scheduler.unstable_scheduleCallback, + cancelCallback = Scheduler.unstable_cancelCallback, + shouldYield = Scheduler.unstable_shouldYield, + requestPaint = Scheduler.unstable_requestPaint, + now = Scheduler.unstable_now, + ImmediatePriority = Scheduler.unstable_ImmediatePriority, + UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + NormalPriority = Scheduler.unstable_NormalPriority, + IdlePriority = Scheduler.unstable_IdlePriority, + rendererID = null, + injectedHook = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function onCommitRoot(root, eventPriority) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + var didError = 128 === (root.current.flags & 128); + switch (eventPriority) { + case 1: + var schedulerPriority = ImmediatePriority; + break; + case 4: + schedulerPriority = UserBlockingPriority; + break; + case 16: + schedulerPriority = NormalPriority; + break; + case 536870912: + schedulerPriority = IdlePriority; + break; + default: + schedulerPriority = NormalPriority; + } + injectedHook.onCommitFiberRoot( + rendererID, + root, + schedulerPriority, + didError + ); + } catch (err) {} +} +var nextTransitionLane = 64, + nextRetryLane = 4194304; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return 1; + case 2: + return 2; + case 4: + return 4; + case 8: + return 8; + case 16: + return 16; + case 32: + return 32; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return lanes & 4194240; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return lanes & 130023424; + case 134217728: + return 134217728; + case 268435456: + return 268435456; + case 536870912: + return 536870912; + case 1073741824: + return 1073741824; + default: + return lanes; + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return 0; + var nextLanes = 0, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes, + nonIdlePendingLanes = pendingLanes & 268435455; + if (0 !== nonIdlePendingLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? (nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes))); + } else + (nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + 0 !== nonIdlePendingLanes + ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) + : 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes)); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) && + ((suspendedLanes = nextLanes & -nextLanes), + (pingedLanes = wipLanes & -wipLanes), + suspendedLanes >= pingedLanes || + (16 === suspendedLanes && 0 !== (pingedLanes & 4194240))) + ) + return wipLanes; + 0 !== (nextLanes & 4) && (nextLanes |= pendingLanes & 16); + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (pendingLanes = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function computeExpirationTime(lane, currentTime) { + switch (lane) { + case 1: + case 2: + case 4: + return currentTime + 250; + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return currentTime + 5e3; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return -1; + case 134217728: + case 268435456: + case 536870912: + case 1073741824: + return -1; + default: + return -1; + } +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$7 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$7; + remainingLanes[index$7] = 0; + eventTimes[index$7] = -1; + root[index$7] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$8 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$8; + (lane & entangledLanes) | (root[index$8] & entangledLanes) && + (root[index$8] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var currentUpdatePriority = 0; +function lanesToEventPriority(lanes) { + lanes &= -lanes; + return 1 < lanes + ? 4 < lanes + ? 0 !== (lanes & 268435455) + ? 16 + : 536870912 + : 4 + : 1; +} function shim() { throw Error( "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." @@ -1645,7 +1965,8 @@ function describeFunctionComponentFrame(fn, source) { ? describeComponentFrame(fn.displayName || fn.name || null, source, null) : ""; } -var valueStack = [], +var hasOwnProperty = Object.prototype.hasOwnProperty, + valueStack = [], index = -1; function createCursor(defaultValue) { return { current: defaultValue }; @@ -1699,13 +2020,13 @@ function pushTopLevelContextObject(fiber, context, didChange) { } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; - fiber = type.childContextTypes; + type = type.childContextTypes; if ("function" !== typeof instance.getChildContext) return parentContext; instance = instance.getChildContext(); for (var contextKey in instance) - if (!(contextKey in fiber)) + if (!(contextKey in type)) throw Error( - (getComponentName(type) || "Unknown") + + (getComponentNameFromFiber(fiber) || "Unknown") + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.' @@ -1741,383 +2062,103 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor); push(didPerformWorkStackCursor, didChange); } -var rendererID = null, - injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, - Scheduler_now = Scheduler.unstable_now; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; +var syncQueue = null, + includesLegacySyncCallbacks = !1, + isFlushingSyncQueue = !1; +function flushSyncCallbacks() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0, + previousUpdatePriority = currentUpdatePriority; + try { + var queue = syncQueue; + for (currentUpdatePriority = 1; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + syncQueue = null; + includesLegacySyncCallbacks = !1; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), + error); + } finally { + (currentUpdatePriority = previousUpdatePriority), + (isFlushingSyncQueue = !1); + } } + return null; } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +function is(x, y) { + return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); +} +var objectIs = "function" === typeof Object.is ? Object.is : is; +function shallowEqual(objA, objB) { + if (objectIs(objA, objB)) return !0; + if ( + "object" !== typeof objA || + null === objA || + "object" !== typeof objB || + null === objB + ) + return !1; + var keysA = Object.keys(objA), + keysB = Object.keys(objB); + if (keysA.length !== keysB.length) return !1; + for (keysB = 0; keysB < keysA.length; keysB++) + if ( + !hasOwnProperty.call(objB, keysA[keysB]) || + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + ) + return !1; + return !0; +} +function describeFiber(fiber) { + switch (fiber.tag) { case 5: - return 97; - case 3: + return describeComponentFrame(fiber.type, null, null); + case 16: + return describeComponentFrame("Lazy", null, null); + case 13: + return describeComponentFrame("Suspense", null, null); + case 19: + return describeComponentFrame("SuspenseList", null, null); + case 0: case 2: + case 15: + return describeFunctionComponentFrame(fiber.type, null); + case 11: + return describeFunctionComponentFrame(fiber.type.render, null); case 1: - return 95; - case 0: - return 90; + return (fiber = describeFunctionComponentFrame(fiber.type, null)), fiber; default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); + return ""; } } -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; +function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + baseProps = Object.assign({}, baseProps); + Component = Component.defaultProps; + for (var propName in Component) + void 0 === baseProps[propName] && + (baseProps[propName] = Component[propName]); + return baseProps; } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } -} -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; -function is(x, y) { - return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); -} -var objectIs = "function" === typeof Object.is ? Object.is : is, - hasOwnProperty = Object.prototype.hasOwnProperty; -function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; - if ( - "object" !== typeof objA || - null === objA || - "object" !== typeof objB || - null === objB - ) - return !1; - var keysA = Object.keys(objA), - keysB = Object.keys(objB); - if (keysA.length !== keysB.length) return !1; - for (keysB = 0; keysB < keysA.length; keysB++) - if ( - !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) - ) - return !1; - return !0; -} -function describeFiber(fiber) { - switch (fiber.tag) { - case 5: - return describeComponentFrame(fiber.type, null, null); - case 16: - return describeComponentFrame("Lazy", null, null); - case 13: - return describeComponentFrame("Suspense", null, null); - case 19: - return describeComponentFrame("SuspenseList", null, null); - case 0: - case 2: - case 15: - return describeFunctionComponentFrame(fiber.type, null); - case 11: - return describeFunctionComponentFrame(fiber.type.render, null); - case 1: - return (fiber = describeFunctionComponentFrame(fiber.type, null)), fiber; - default: - return ""; - } -} -function resolveDefaultProps(Component, baseProps) { - if (Component && Component.defaultProps) { - baseProps = Object.assign({}, baseProps); - Component = Component.defaultProps; - for (var propName in Component) - void 0 === baseProps[propName] && - (baseProps[propName] = Component[propName]); - return baseProps; - } - return baseProps; + return baseProps; } var valueCursor = createCursor(null), currentlyRenderingFiber = null, lastContextDependency = null, - lastContextWithAllBitsObserved = null; + lastFullyObservedContext = null; function resetContextDependencies() { - lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; + lastFullyObservedContext = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue2 = currentValue; + context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2137,44 +2178,41 @@ function scheduleWorkOnParentPath(parent, renderLanes) { } function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; - lastContextWithAllBitsObserved = lastContextDependency = null; + lastFullyObservedContext = lastContextDependency = null; workInProgress = workInProgress.dependencies; null !== workInProgress && null !== workInProgress.firstContext && (0 !== (workInProgress.lanes & renderLanes) && (didReceiveUpdate = !0), (workInProgress.firstContext = null)); } -function readContext(context, observedBits) { - if ( - lastContextWithAllBitsObserved !== context && - !1 !== observedBits && - 0 !== observedBits - ) { - if ("number" !== typeof observedBits || 1073741823 === observedBits) - (lastContextWithAllBitsObserved = context), (observedBits = 1073741823); - observedBits = { context: context, observedBits: observedBits, next: null }; - if (null === lastContextDependency) { +function readContext(context) { + var value = context._currentValue2; + if (lastFullyObservedContext !== context) + if ( + ((context = { context: context, memoizedValue: value, next: null }), + null === lastContextDependency) + ) { if (null === currentlyRenderingFiber) throw 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; + lastContextDependency = context; currentlyRenderingFiber.dependencies = { lanes: 0, - firstContext: observedBits, + firstContext: context, responders: null }; - } else lastContextDependency = lastContextDependency.next = observedBits; - } - return context._currentValue2; + } else lastContextDependency = lastContextDependency.next = context; + return value; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2200,14 +2238,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 4194240))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2276,111 +2332,111 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + 0 !== pendingQueue.lane && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2436,7 +2492,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2447,7 +2504,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2457,7 +2515,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2529,7 +2588,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && @@ -2551,7 +2609,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var isArray = Array.isArray; function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2604,25 +2661,22 @@ function coerceRef(returnFiber, current, element) { return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if ("textarea" !== returnFiber.type) - throw 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) + - "). If you meant to render a collection of children, use an array instead." - ); + returnFiber = Object.prototype.toString.call(newChild); + throw Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === returnFiber + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : returnFiber) + + "). If you meant to render a collection of children, use an array instead." + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2654,16 +2708,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2678,7 +2732,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2767,7 +2830,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (newChild = createFiberFromFragment( newChild, @@ -2792,22 +2855,14 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key ? null : updateFragment(returnFiber, oldFiber, newChild, lanes, null); @@ -2835,15 +2890,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -2854,7 +2901,7 @@ function ChildReconciler(shouldTrackSideEffects) { updatePortal(returnFiber, existingChildren, newChild, lanes) ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (existingChildren = existingChildren.get(newIdx) || null), updateFragment(returnFiber, existingChildren, newChild, lanes, null) @@ -3037,55 +3084,49 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.type === REACT_FRAGMENT_TYPE && null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); - var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) + if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; + var key = newChild.key; for ( isUnkeyedTopLevelFragment = currentFirstChild; null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + if (isUnkeyedTopLevelFragment.key === key) { + key = newChild.type; + if (key === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === key) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3161,6 +3202,22 @@ function ChildReconciler(shouldTrackSideEffects) { } return placeSingleChild(returnFiber); } + if (isArrayImpl(newChild)) + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + if (getIteratorFn(newChild)) + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + throwOnInvalidObjectType(returnFiber, newChild); + } if ("string" === typeof newChild || "number" === typeof newChild) return ( (newChild = "" + newChild), @@ -3179,21 +3236,6 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); - if (isArray(newChild)) - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - if (getIteratorFn(newChild)) - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - isObject && throwOnInvalidObjectType(returnFiber, newChild); if ("undefined" === typeof newChild && !isUnkeyedTopLevelFragment) switch (returnFiber.tag) { case 1: @@ -3201,7 +3243,7 @@ function ChildReconciler(shouldTrackSideEffects) { case 11: case 15: throw Error( - (getComponentName(returnFiber.type) || "Component") + + (getComponentNameFromFiber(returnFiber) || "Component") + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." ); } @@ -3263,7 +3305,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3415,10 +3457,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3443,22 +3486,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3498,7 +3552,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3528,25 +3582,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$11 = 31 - clz32(lanes), - lane = 1 << index$11; - entanglements[index$11] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3573,6 +3615,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3598,6 +3642,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3646,7 +3692,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3654,10 +3700,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(1049600, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3718,19 +3764,18 @@ function updateMemo(nextCreate, deps) { return nextCreate; } function startTransition(setPending, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = 1; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }); + var previousPriority = currentUpdatePriority; + currentUpdatePriority = + 0 !== previousPriority && 4 > previousPriority ? previousPriority : 4; + setPending(!0); + var prevTransition = ReactCurrentBatchConfig$1.transition; + ReactCurrentBatchConfig$1.transition = 1; + try { + setPending(!1), callback(); + } finally { + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$1.transition = prevTransition); + } } function dispatchAction(fiber, queue, action) { var eventTime = requestEventTime(), @@ -3742,33 +3787,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 4194240) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3825,6 +3892,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3866,7 +3935,7 @@ var ContextOnlyDispatcher = { isPending = _mountState2[0]; _mountState2 = startTransition.bind(null, _mountState2[1]); mountWorkInProgressHook().memoizedState = _mountState2; - return [_mountState2, isPending]; + return [isPending, _mountState2]; }, useMutableSource: function(source, getSnapshot, subscribe) { var hook = mountWorkInProgressHook(); @@ -3915,8 +3984,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = updateReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -3957,8 +4027,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = rerenderReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4015,7 +4086,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4091,14 +4162,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4115,31 +4187,39 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 1)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - markSpawnedWork(1073741824), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, current), - null - ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= nextProps; + } else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4149,7 +4229,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4174,7 +4254,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4334,7 +4414,8 @@ function updateClassComponent( oldState, newState, oldContext - )) + ) || + !1) ? (getDerivedStateFromProps || ("function" !== typeof instance.UNSAFE_componentWillUpdate && "function" !== typeof instance.componentWillUpdate) || @@ -4349,7 +4430,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4357,7 +4438,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4371,7 +4452,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4392,7 +4473,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4440,18 +4521,21 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; +} function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4468,7 +4552,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4480,10 +4566,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432), + (workInProgress.lanes = 4194304), current ); renderLanes = createFiberFromOffscreen( @@ -4509,8 +4596,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4537,8 +4627,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4561,10 +4654,10 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 8 && + workInProgress.mode & 2 && ((progressedPrimaryFragment.actualDuration = 0), (progressedPrimaryFragment.actualStartTime = -1), (progressedPrimaryFragment.selfBaseDuration = 0), @@ -4599,13 +4692,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4615,33 +4709,27 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + var mode = workInProgress.mode; + current = current.child; + var currentFallbackChildFragment = current.sibling, + primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 1) && workInProgress.child !== current ? ((primaryChildren = workInProgress.child), (primaryChildren.childLanes = 0), (primaryChildren.pendingProps = primaryChildProps), - workInProgress.mode & 8 && + workInProgress.mode & 2 && ((primaryChildren.actualDuration = 0), (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration), - (primaryChildren.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration)), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (primaryChildren.selfBaseDuration = current.selfBaseDuration), + (primaryChildren.treeBaseDuration = current.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4666,8 +4754,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4677,16 +4764,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4695,9 +4780,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4720,7 +4805,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4741,8 +4826,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4764,19 +4848,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4787,25 +4863,33 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } - return null; + return workInProgress.child; +} +function hadNoMutationsEffects(current, completedWork) { + if (null !== current && current.child === completedWork.child) return !0; + if (0 !== (completedWork.flags & 16)) return !1; + for (current = completedWork.child; null !== current; ) { + if (0 !== (current.flags & 6454) || 0 !== (current.subtreeFlags & 6454)) + return !1; + current = current.sibling; + } + return !0; } var appendAllChildren, updateHostContainer, @@ -4922,21 +5006,24 @@ function appendAllChildrenToContainer( node = node.sibling; } } -updateHostContainer = function(workInProgress) { +updateHostContainer = function(current, workInProgress) { var portalOrRoot = workInProgress.stateNode; - if (null !== workInProgress.firstEffect) { - var container = portalOrRoot.containerInfo, - newChildSet = createChildNodeSet(container); + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); portalOrRoot.pendingChildren = newChildSet; workInProgress.flags |= 4; - completeRoot(container, newChildSet); + completeRoot(current, newChildSet); } }; updateHostComponent$1 = function(current, workInProgress, type, newProps) { type = current.stateNode; var oldProps = current.memoizedProps; - if ((current = null === workInProgress.firstEffect) && oldProps === newProps) + if ( + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps + ) workInProgress.stateNode = type; else { var recyclableInstance = workInProgress.stateNode; @@ -4954,15 +5041,15 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { current && null === updatePayload ? (workInProgress.stateNode = type) : ((newProps = updatePayload), - (recyclableInstance = type.node), + (oldProps = type.node), (type = { node: current ? null !== newProps - ? cloneNodeWithNewProps(recyclableInstance, newProps) - : cloneNode(recyclableInstance) + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -5008,6 +5095,66 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (lastTailNode$65.sibling = null); } } +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + if (0 !== (completedWork.mode & 2)) { + for ( + var treeBaseDuration$67 = completedWork.selfBaseDuration, + child$68 = completedWork.child; + null !== child$68; + + ) + (newChildLanes |= child$68.lanes | child$68.childLanes), + (subtreeFlags |= child$68.subtreeFlags & 1835008), + (subtreeFlags |= child$68.flags & 1835008), + (treeBaseDuration$67 += child$68.treeBaseDuration), + (child$68 = child$68.sibling); + completedWork.treeBaseDuration = treeBaseDuration$67; + } else + for ( + treeBaseDuration$67 = completedWork.child; + null !== treeBaseDuration$67; + + ) + (newChildLanes |= + treeBaseDuration$67.lanes | treeBaseDuration$67.childLanes), + (subtreeFlags |= treeBaseDuration$67.subtreeFlags & 1835008), + (subtreeFlags |= treeBaseDuration$67.flags & 1835008), + (treeBaseDuration$67.return = completedWork), + (treeBaseDuration$67 = treeBaseDuration$67.sibling); + else if (0 !== (completedWork.mode & 2)) { + treeBaseDuration$67 = completedWork.actualDuration; + child$68 = completedWork.selfBaseDuration; + for (var child = completedWork.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (subtreeFlags |= child.subtreeFlags), + (subtreeFlags |= child.flags), + (treeBaseDuration$67 += child.actualDuration), + (child$68 += child.treeBaseDuration), + (child = child.sibling); + completedWork.actualDuration = treeBaseDuration$67; + completedWork.treeBaseDuration = child$68; + } else + for ( + treeBaseDuration$67 = completedWork.child; + null !== treeBaseDuration$67; + + ) + (newChildLanes |= + treeBaseDuration$67.lanes | treeBaseDuration$67.childLanes), + (subtreeFlags |= treeBaseDuration$67.subtreeFlags), + (subtreeFlags |= treeBaseDuration$67.flags), + (treeBaseDuration$67.return = completedWork), + (treeBaseDuration$67 = treeBaseDuration$67.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -5021,76 +5168,81 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); else { if (!newProps) { if (null === workInProgress.stateNode) throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); + bubbleProperties(workInProgress); return null; } requiredContext(contextStackCursor$1.current); current = nextReactTag; nextReactTag += 2; - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); - rootContainerInstance = createNode( + renderLanes = createNode( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderLanes, + type, newProps, workInProgress ); - current = { node: rootContainerInstance, canonical: current }; + current = { node: renderLanes, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 128); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5106,30 +5258,30 @@ function completeWork(current, workInProgress, renderLanes) { "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); current = requiredContext(rootInstanceStackCursor.current); - rootContainerInstance = requiredContext(contextStackCursor$1.current); + renderLanes = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - rootContainerInstance, + renderLanes, workInProgress ); } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return ( (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 8) && + 0 !== (workInProgress.mode & 2) && transferActualDuration(workInProgress), workInProgress ); newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5144,89 +5296,100 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } newProps && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 2) && + newProps && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), + (renderLanes = newProps), (updatePayload = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (renderLanes = rootContainerInstance.alternate), - null === renderLanes - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = updatePayload), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null), - (rootContainerInstance.selfBaseDuration = 0), - (rootContainerInstance.treeBaseDuration = 0)) - : ((rootContainerInstance.childLanes = - renderLanes.childLanes), - (rootContainerInstance.lanes = renderLanes.lanes), - (rootContainerInstance.child = renderLanes.child), - (rootContainerInstance.memoizedProps = - renderLanes.memoizedProps), - (rootContainerInstance.memoizedState = - renderLanes.memoizedState), - (rootContainerInstance.updateQueue = - renderLanes.updateQueue), - (rootContainerInstance.type = renderLanes.type), - (updatePayload = renderLanes.dependencies), - (rootContainerInstance.dependencies = + (renderLanes.flags &= 1835010), + (type = renderLanes.alternate), + null === type + ? ((renderLanes.childLanes = 0), + (renderLanes.lanes = updatePayload), + (renderLanes.child = null), + (renderLanes.subtreeFlags = 0), + (renderLanes.memoizedProps = null), + (renderLanes.memoizedState = null), + (renderLanes.updateQueue = null), + (renderLanes.dependencies = null), + (renderLanes.stateNode = null), + (renderLanes.selfBaseDuration = 0), + (renderLanes.treeBaseDuration = 0)) + : ((renderLanes.childLanes = type.childLanes), + (renderLanes.lanes = type.lanes), + (renderLanes.child = type.child), + (renderLanes.subtreeFlags = 0), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = type.memoizedProps), + (renderLanes.memoizedState = type.memoizedState), + (renderLanes.updateQueue = type.updateQueue), + (renderLanes.type = type.type), + (updatePayload = type.dependencies), + (renderLanes.dependencies = null === updatePayload ? null : { lanes: updatePayload.lanes, firstContext: updatePayload.firstContext }), - (rootContainerInstance.selfBaseDuration = - renderLanes.selfBaseDuration), - (rootContainerInstance.treeBaseDuration = - renderLanes.treeBaseDuration)), + (renderLanes.selfBaseDuration = type.selfBaseDuration), + (renderLanes.treeBaseDuration = type.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, @@ -5236,80 +5399,74 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; case 22: case 23: return ( popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), null !== current && - (null !== current.memoizedState) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 1)) || + bubbleProperties(workInProgress), null ); } @@ -5324,9 +5481,9 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 2) && transferActualDuration(workInProgress), workInProgress) : null; @@ -5336,11 +5493,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5348,9 +5505,9 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 2) && transferActualDuration(workInProgress), workInProgress) : null @@ -5360,10 +5517,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5442,164 +5601,163 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$82 = finishedRoot.create; - finishedRoot.destroy = create$82(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$82 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$82; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$82 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$82, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode.canonical; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$86 = effect.create; + effect.destroy = create$86(); } - return; - case 5: - null === current && finishedWork.flags & 4 && shim(); - return; - case 6: - return; - case 4: - return; - case 12: - create$82 = finishedWork.memoizedProps.onRender; - _effect = commitTime; - "function" === typeof create$82 && - create$82( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - _effect, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } -function detachFiberMutation(fiber) { - fiber.alternate = null; +function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; + null !== alternate && + ((fiber.alternate = null), detachFiberAfterEffects(alternate)); fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function commitWork(current, finishedWork) { @@ -5608,19 +5766,7 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedWork = current = current.next; - do { - if (3 === (finishedWork.tag & 3)) { - var destroy = finishedWork.destroy; - finishedWork.destroy = void 0; - void 0 !== destroy && destroy(); - } - finishedWork = finishedWork.next; - } while (finishedWork !== current); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 12: return; @@ -5641,7 +5787,6 @@ function commitWork(current, finishedWork) { case 1: case 5: case 6: - case 20: break a; case 3: case 4: @@ -5662,24 +5807,278 @@ function attachSuspenseRetryListeners(finishedWork) { wakeables.forEach(function(wakeable) { var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); retryCache.has(wakeable) || - (!0 !== wakeable.__reactDoNotTraceInteractions && - (retry = tracing.unstable_wrap(retry)), - retryCache.add(wakeable), - wakeable.then(retry, retry)); + (retryCache.add(wakeable), wakeable.then(retry, retry)); }); } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; +function commitMutationEffects(root, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) { + var childToDelete = firstChild[i]; + try { + a: for (var node = childToDelete; ; ) { + var current = node; + if ( + injectedHook && + "function" === typeof injectedHook.onCommitFiberUnmount + ) + try { + injectedHook.onCommitFiberUnmount(rendererID, current); + } catch (err) {} + switch (current.tag) { + case 0: + case 11: + case 14: + case 15: + var updateQueue = current.updateQueue; + if (null !== updateQueue) { + var lastEffect = updateQueue.lastEffect; + if (null !== lastEffect) { + var firstEffect = lastEffect.next, + effect = firstEffect; + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + if (void 0 !== destroy && 0 !== (tag & 2)) { + _effect = current; + var nearestMountedAncestor = root; + try { + destroy(); + } catch (error) { + captureCommitPhaseError( + _effect, + nearestMountedAncestor, + error + ); + } + } + effect = effect.next; + } while (effect !== firstEffect); + } + } + break; + case 1: + safelyDetachRef(current, root); + var instance = current.stateNode; + if ("function" === typeof instance.componentWillUnmount) + try { + (effect = current), + (_effect = instance), + (_effect.props = effect.memoizedProps), + (_effect.state = effect.memoizedState), + _effect.componentWillUnmount(); + } catch (unmountError) { + captureCommitPhaseError(current, root, unmountError); + } + break; + case 5: + safelyDetachRef(current, root); + break; + case 4: + createChildNodeSet(current.stateNode.containerInfo); + } + if (null !== node.child) + (node.child.return = node), (node = node.child); + else { + if (node === childToDelete) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === childToDelete) + break a; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + } + var alternate = childToDelete.alternate; + null !== alternate && (alternate.return = null); + childToDelete.return = null; + } catch (error) { + captureCommitPhaseError(childToDelete, root, error); + } + } + firstChild = root.child; + if (0 !== (root.subtreeFlags & 6454) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var flags = root.flags; + if (flags & 256) { + var current$jscomp$0 = root.alternate; + if (null !== current$jscomp$0) { + var currentRef = current$jscomp$0.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + root.flags &= -3; + break; + case 6: + root.flags &= -3; + commitWork(root.alternate, root); + break; + case 2048: + root.flags &= -2049; + break; + case 2052: + root.flags &= -2049; + commitWork(root.alternate, root); + break; + case 4: + commitWork(root.alternate, root); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; + } + } +} +function commitLayoutEffects(finishedWork) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; + try { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, firstChild); + break; + case 1: + var instance = firstChild.stateNode; + if (firstChild.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + firstChild.elementType === firstChild.type + ? current.memoizedProps + : resolveDefaultProps( + firstChild.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = firstChild.updateQueue; + null !== updateQueue && + commitUpdateQueue(firstChild, updateQueue, instance); + break; + case 3: + var updateQueue$87 = firstChild.updateQueue; + if (null !== updateQueue$87) { + var instance$88 = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { + case 5: + instance$88 = firstChild.child.stateNode.canonical; + break; + case 1: + instance$88 = firstChild.child.stateNode; + } + commitUpdateQueue(firstChild, updateQueue$87, instance$88); + } + break; + case 5: + null === current && firstChild.flags & 4 && shim(); + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = firstChild.memoizedProps.onRender; + instance$88 = commitTime; + current = null === current ? "mount" : "update"; + "function" === typeof onRender && + onRender( + firstChild.memoizedProps.id, + current, + firstChild.actualDuration, + firstChild.treeBaseDuration, + firstChild.actualStartTime, + instance$88 + ); + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (firstChild.flags & 256) { + instance$88 = void 0; + var ref = firstChild.ref; + if (null !== ref) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { + case 5: + instance$88 = instance$jscomp$0.canonical; + break; + default: + instance$88 = instance$jscomp$0; + } + "function" === typeof ref + ? ref(instance$88) + : (ref.current = instance$88); + } + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + } + if (firstChild === fiber) { + nextEffect = null; + break; + } + instance$88 = firstChild.sibling; + if (null !== instance$88) { + instance$88.return = firstChild.return; + nextEffect = instance$88; + break; + } + nextEffect = firstChild.return; + } + } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -5688,66 +6087,41 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, - pendingPassiveEffectsRenderPriority = 90, pendingPassiveEffectsLanes = 0, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], - rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, - spawnedWorkDuringRender = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { - return 0 !== (executionContext & 48) + return 0 !== (executionContext & 24) ? now() : -1 !== currentEventTime ? currentEventTime : (currentEventTime = now()); } function requestUpdateLane(fiber) { - fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } - fiber = getCurrentPriorityLevel(); - 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) - : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); - return fiber; + if (0 === (fiber.mode & 1)) return 1; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); + fiber = currentUpdatePriority; + return 0 !== fiber ? fiber : 16; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (50 < nestedUpdateCount) @@ -5756,30 +6130,23 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { 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 = markUpdateLaneFromFiberToRoot(fiber, lane); - if (null === fiber) return null; - markRootUpdated(fiber, lane, eventTime); - fiber === workInProgressRoot && + var root = markUpdateLaneFromFiberToRoot(fiber, lane); + if (null === root) return null; + markRootUpdated(root, lane, eventTime); + root === workInProgressRoot && ((workInProgressRootUpdatedLanes |= lane), 4 === workInProgressRootExitStatus && - markRootSuspended$1(fiber, workInProgressRootRenderLanes)); - var priorityLevel = getCurrentPriorityLevel(); + markRootSuspended$1(root, workInProgressRootRenderLanes)); 1 === lane - ? 0 !== (executionContext & 8) && 0 === (executionContext & 48) - ? (schedulePendingInteractions(fiber, lane), performSyncWorkOnRoot(fiber)) - : (ensureRootIsScheduled(fiber, eventTime), - schedulePendingInteractions(fiber, lane), + ? 0 !== (executionContext & 4) && 0 === (executionContext & 24) + ? performSyncWorkOnRoot(root) + : (ensureRootIsScheduled(root, eventTime), 0 === executionContext && + 0 === (fiber.mode & 1) && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue())) - : (0 === (executionContext & 4) || - (98 !== priorityLevel && 99 !== priorityLevel) || - (null === rootsWithPendingDiscreteUpdates - ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) - : rootsWithPendingDiscreteUpdates.add(fiber)), - ensureRootIsScheduled(fiber, eventTime), - schedulePendingInteractions(fiber, lane)); - mostRecentlyUpdatedRoot = fiber; + includesLegacySyncCallbacks && flushSyncCallbacks())) + : ensureRootIsScheduled(root, eventTime); + return root; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -5808,17 +6175,8 @@ function ensureRootIsScheduled(root, currentTime) { lane = 1 << index$5, expirationTime = expirationTimes[index$5]; if (-1 === expirationTime) { - if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { - expirationTime = currentTime; - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; - expirationTimes[index$5] = - 10 <= priority - ? expirationTime + 250 - : 6 <= priority - ? expirationTime + 5e3 - : -1; - } + if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) + expirationTimes[index$5] = computeExpirationTime(lane, currentTime); } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } @@ -5826,47 +6184,58 @@ function ensureRootIsScheduled(root, currentTime) { root, root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); - currentTime = return_highestLanePriority; if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode), + null !== existingCallbackNode && cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); + (root.callbackPriority = 0); + else if ( + ((currentTime = suspendedLanes & -suspendedLanes), + root.callbackPriority !== currentTime) + ) { + null != existingCallbackNode && cancelCallback(existingCallbackNode); + if (1 === currentTime) + 0 === root.tag + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + (includesLegacySyncCallbacks = !0), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)) + : ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), + (existingCallbackNode = null); + else { + switch (lanesToEventPriority(suspendedLanes)) { + case 1: + existingCallbackNode = ImmediatePriority; + break; + case 4: + existingCallbackNode = UserBlockingPriority; + break; + case 16: + existingCallbackNode = NormalPriority; + break; + case 536870912: + existingCallbackNode = IdlePriority; + break; + default: + existingCallbackNode = NormalPriority; + } + existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ); } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); root.callbackPriority = currentTime; root.callbackNode = existingCallbackNode; } } -function performConcurrentWorkOnRoot(root) { +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; - if (0 !== (executionContext & 48)) + currentEventTransitionLane = 0; + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; if (flushPassiveEffects() && root.callbackNode !== originalCallbackNode) @@ -5876,44 +6245,45 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - var lanes$jscomp$0 = lanes; - var exitStatus = executionContext; - executionContext |= 16; - var prevDispatcher = pushDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== lanes$jscomp$0 - ) - (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, lanes$jscomp$0), - startWorkOnPendingInteractions(root, lanes$jscomp$0); - lanes$jscomp$0 = pushInteractions(root); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = lanes$jscomp$0; - ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = exitStatus; - null !== workInProgress - ? (exitStatus = 0) - : ((workInProgressRoot = null), - (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && - ((executionContext |= 64), + var JSCompiler_inline_result = + 0 !== (lanes & root.expiredLanes) ? !1 : 0 === (lanes & 30); + if (JSCompiler_inline_result && !didTimeout) { + didTimeout = lanes; + JSCompiler_inline_result = executionContext; + executionContext |= 8; + var prevDispatcher = pushDispatcher(); + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== didTimeout + ) + (workInProgressRootRenderTargetTime = now() + 500), + prepareFreshStack(root, didTimeout); + do + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + ReactCurrentDispatcher$2.current = prevDispatcher; + executionContext = JSCompiler_inline_result; + null !== workInProgress + ? (didTimeout = 0) + : ((workInProgressRoot = null), + (workInProgressRootRenderLanes = 0), + (didTimeout = workInProgressRootExitStatus)); + } else didTimeout = renderRootSync(root, lanes); + if (0 !== didTimeout) { + 2 === didTimeout && + ((executionContext |= 32), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + (JSCompiler_inline_result = getLanesToRetrySynchronouslyOnError(root)), + 0 !== JSCompiler_inline_result && + ((lanes = JSCompiler_inline_result), + (didTimeout = renderRootSync(root, JSCompiler_inline_result)))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -5921,7 +6291,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -5931,20 +6301,20 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 130023424) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; - prevDispatcher = root.suspendedLanes; - if ((prevDispatcher & lanes) !== lanes) { + JSCompiler_inline_result = root.suspendedLanes; + if ((JSCompiler_inline_result & lanes) !== lanes) { requestEventTime(); - root.pingedLanes |= root.suspendedLanes & prevDispatcher; + root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result; break; } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -5952,16 +6322,17 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; - for (prevDispatcher = -1; 0 < lanes; ) { + if ((lanes & 4194240) === lanes) break; + didTimeout = root.eventTimes; + for (JSCompiler_inline_result = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); - lanes$jscomp$0 = 1 << index$4; - index$4 = exitStatus[index$4]; - index$4 > prevDispatcher && (prevDispatcher = index$4); - lanes &= ~lanes$jscomp$0; + prevDispatcher = 1 << index$4; + index$4 = didTimeout[index$4]; + index$4 > JSCompiler_inline_result && + (JSCompiler_inline_result = index$4); + lanes &= ~prevDispatcher; } - lanes = prevDispatcher; + lanes = JSCompiler_inline_result; lanes = now() - lanes; lanes = (120 > lanes @@ -6004,33 +6375,26 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$9 = 31 - clz32(suspendedLanes), - lane = 1 << index$9; - root[index$9] = -1; + var index$6 = 31 - clz32(suspendedLanes), + lane = 1 << index$6; + root[index$6] = -1; suspendedLanes &= ~lane; } } function performSyncWorkOnRoot(root) { - if (0 !== (executionContext & 48)) + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( - root === workInProgressRoot && - 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); - 0 !== root.tag && - 2 === exitStatus && - ((executionContext |= 64), - root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + var lanes = getNextLanes(root, 0); + if (0 === (lanes & 1)) return ensureRootIsScheduled(root, now()), null; + var exitStatus = renderRootSync(root, lanes); + if (0 !== root.tag && 2 === exitStatus) { + executionContext |= 32; + root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + 0 !== errorRetryLanes && + ((lanes = errorRetryLanes), (exitStatus = renderRootSync(root, lanes))); + } if (1 === exitStatus) throw ((exitStatus = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6043,11 +6407,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6087,7 +6446,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6097,11 +6456,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; - spawnedWorkDuringRender = null; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6131,7 +6508,7 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress = null; break; } - erroredWork.mode & 8 && + erroredWork.mode & 2 && stopProfilerTimerIfRunningAndRecordDelta(erroredWork, !0); a: { var root = root$jscomp$0, @@ -6139,15 +6516,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6158,15 +6538,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$77 = returnFiber; + workInProgress$81 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { - var nextState = workInProgress$77.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$81.tag)) { + var nextState = workInProgress$81.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$77.memoizedProps; + var props = workInProgress$81.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6178,16 +6558,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$77.updateQueue; + var wakeables = workInProgress$81.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$77.updateQueue = updateQueue; + workInProgress$81.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$77.mode & 2)) { - workInProgress$77.flags |= 64; + if ( + 0 === (workInProgress$81.mode & 1) && + workInProgress$81 !== returnFiber + ) { + workInProgress$81.flags |= 128; sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6218,61 +6601,61 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$77.flags |= 8192; - workInProgress$77.lanes = thrownValue; + workInProgress$81.flags |= 16384; + workInProgress$81.lanes = thrownValue; break a; } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$81 = workInProgress$81.return; + } while (null !== workInProgress$81); value = Error( - (getComponentName(sourceFiber.type) || "A React component") + + (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." ); } 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$77 = returnFiber; + workInProgress$81 = returnFiber; do { - switch (workInProgress$77.tag) { + switch (workInProgress$81.tag) { case 3: root = value; - workInProgress$77.flags |= 8192; + workInProgress$81.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$78 = createRootErrorUpdate( - workInProgress$77, + workInProgress$81.lanes |= thrownValue; + var update$82 = createRootErrorUpdate( + workInProgress$81, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$78); + enqueueCapturedUpdate(workInProgress$81, update$82); break a; case 1: root = value; - var ctor = workInProgress$77.type, - instance = workInProgress$77.stateNode; + var ctor = workInProgress$81.type, + instance = workInProgress$81.stateNode; if ( - 0 === (workInProgress$77.flags & 64) && + 0 === (workInProgress$81.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$77.flags |= 8192; + workInProgress$81.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$81 = createClassErrorUpdate( - workInProgress$77, + workInProgress$81.lanes |= thrownValue; + var update$85 = createClassErrorUpdate( + workInProgress$81, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$81); + enqueueCapturedUpdate(workInProgress$81, update$85); break a; } } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$81 = workInProgress$81.return; + } while (null !== workInProgress$81); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6290,18 +6673,12 @@ function pushDispatcher() { ReactCurrentDispatcher$2.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } -function pushInteractions(root) { - var prevInteractions = tracing.__interactionsRef.current; - tracing.__interactionsRef.current = root.memoizedInteractions; - return prevInteractions; -} function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; - executionContext |= 16; + executionContext |= 8; var prevDispatcher = pushDispatcher(); - if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) - prepareFreshStack(root, lanes), startWorkOnPendingInteractions(root, lanes); - lanes = pushInteractions(root); + (workInProgressRoot === root && workInProgressRootRenderLanes === lanes) || + prepareFreshStack(root, lanes); do try { workLoopSync(); @@ -6311,7 +6688,6 @@ function renderRootSync(root, lanes) { } while (1); resetContextDependencies(); - tracing.__interactionsRef.current = lanes; executionContext = prevExecutionContext; ReactCurrentDispatcher$2.current = prevDispatcher; if (null !== workInProgress) @@ -6326,12 +6702,12 @@ function workLoopSync() { for (; null !== workInProgress; ) performUnitOfWork(workInProgress); } function workLoopConcurrent() { - for (; null !== workInProgress && !Scheduler_shouldYield(); ) + for (; null !== workInProgress && !shouldYield(); ) performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 8) + 0 !== (unitOfWork.mode & 2) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current = beginWork$1(current, unitOfWork, subtreeRenderLanes)), @@ -6348,8 +6724,8 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - if (0 === (completedWork.mode & 8)) + if (0 === (completedWork.flags & 8192)) { + if (0 === (completedWork.mode & 2)) current = completeWork(current, completedWork, subtreeRenderLanes); else { var fiber = completedWork; @@ -6362,65 +6738,14 @@ function completeUnitOfWork(unitOfWork) { workInProgress = current; return; } - current = completedWork; - if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) - ) { - fiber = 0; - if (0 !== (current.mode & 8)) { - for ( - var actualDuration = current.actualDuration, - treeBaseDuration = current.selfBaseDuration, - shouldBubbleActualDurations = - null === current.alternate || - current.child !== current.alternate.child, - child = current.child; - null !== child; - - ) - (fiber |= child.lanes | child.childLanes), - shouldBubbleActualDurations && - (actualDuration += child.actualDuration), - (treeBaseDuration += child.treeBaseDuration), - (child = child.sibling); - 13 === current.tag && - null !== current.memoizedState && - ((shouldBubbleActualDurations = current.child), - null !== shouldBubbleActualDurations && - (treeBaseDuration -= - shouldBubbleActualDurations.treeBaseDuration)); - current.actualDuration = actualDuration; - current.treeBaseDuration = treeBaseDuration; - } else - for (actualDuration = current.child; null !== actualDuration; ) - (fiber |= actualDuration.lanes | actualDuration.childLanes), - (actualDuration = actualDuration.sibling); - current.childLanes = fiber; - } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } - if (0 !== (completedWork.mode & 8)) { + if (0 !== (completedWork.mode & 2)) { stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1); current = completedWork.actualDuration; for (fiber = completedWork.child; null !== fiber; ) @@ -6428,8 +6753,9 @@ function completeUnitOfWork(unitOfWork) { completedWork.actualDuration = current; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6441,14 +6767,22 @@ function completeUnitOfWork(unitOfWork) { 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } function commitRoot(root) { - var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig$2.transition; + try { + (ReactCurrentBatchConfig$2.transition = 0), + (currentUpdatePriority = 1), + commitRootImpl(root, previousUpdateLanePriority); + } finally { + (ReactCurrentBatchConfig$2.transition = prevTransition), + (currentUpdatePriority = previousUpdateLanePriority); + } return null; } function commitRootImpl(root, renderPriorityLevel) { do flushPassiveEffects(); while (null !== rootWithPendingPassiveEffects); - if (0 !== (executionContext & 48)) + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); var finishedWork = root.finishedWork, lanes = root.finishedLanes; @@ -6460,384 +6794,208 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$10 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$10; - remainingLanes$jscomp$0[index$10] = 0; - eventTimes[index$10] = -1; - expirationTimes[index$10] = -1; - noLongerPendingLanes &= ~lane; - } - null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && - rootsWithPendingDiscreteUpdates.has(root) && - rootsWithPendingDiscreteUpdates.delete(root); + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; - executionContext |= 32; - eventTimes = pushInteractions(root); - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { + remainingLanes = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = currentUpdatePriority; + currentUpdatePriority = 1; + var prevExecutionContext = executionContext; + executionContext |= 16; + ReactCurrentOwner$2.current = null; + commitBeforeMutationEffects(root, finishedWork); commitTime = now$1(); - nextEffect = remainingLanes; - do - try { - for (; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - nextEffect.flags &= -3; - break; - case 6: - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - expirationTimes = nextEffect; - a: for (index$10 = noLongerPendingLanes = expirationTimes; ; ) { - lane = index$10; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, lane); - } catch (err) {} - switch (lane.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = lane.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next, - effect = firstEffect; - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (tag & 4)) - enqueuePendingPassiveHookEffectUnmount( - lane, - effect - ); - else { - _effect2 = lane; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } - } - effect = effect.next; - } while (effect !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(lane); - var instance = lane.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (effect = lane), - (_effect2 = instance), - (_effect2.props = effect.memoizedProps), - (_effect2.state = effect.memoizedState), - _effect2.componentWillUnmount(); - } catch (unmountError) { - captureCommitPhaseError(lane, unmountError); - } - break; - case 5: - safelyDetachRef(lane); - break; - case 4: - createChildNodeSet(lane.stateNode.containerInfo); - } - if (null !== index$10.child) - (index$10.child.return = index$10), - (index$10 = index$10.child); - else { - if (index$10 === noLongerPendingLanes) break; - for (; null === index$10.sibling; ) { - if ( - null === index$10.return || - index$10.return === noLongerPendingLanes - ) - break a; - index$10 = index$10.return; - } - index$10.sibling.return = index$10.return; - index$10 = index$10.sibling; - } - } - var alternate = expirationTimes.alternate; - detachFiberMutation(expirationTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$90) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$90); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); + commitMutationEffects(root, finishedWork); root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance$jscomp$0.canonical; - break; - default: - current = instance$jscomp$0; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$91) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$91); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; + commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - tracing.__interactionsRef.current = eventTimes; - executionContext = remainingLanes$jscomp$0; + executionContext = prevExecutionContext; + currentUpdatePriority = previousPriority; + ReactCurrentBatchConfig$2.transition = remainingLanes; } else (root.current = finishedWork), (commitTime = now$1()); - if ((flags$jscomp$0 = rootDoesHavePassiveEffects)) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (ref = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((instance$jscomp$0 = nextEffect), - (instance$jscomp$0.sibling = null), - (instance$jscomp$0.stateNode = null)), - (nextEffect = ref); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; - if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) - for ( - ref = spawnedWorkDuringRender, - spawnedWorkDuringRender = null, - instance$jscomp$0 = 0; - instance$jscomp$0 < ref.length; - instance$jscomp$0++ - ) - scheduleInteractions( - root, - ref[instance$jscomp$0], - root.memoizedInteractions - ); - schedulePendingInteractions(root, remainingLanes); - } else legacyErrorBoundariesThatAlreadyFailed = null; - flags$jscomp$0 || finishPendingInteractions(root, lanes); - 1 === remainingLanes + 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - renderPriorityLevel, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), (root = firstUncaughtError), (firstUncaughtError = null), root); - if (0 !== (executionContext & 8)) return null; - flushSyncCallbackQueue(); + if (0 !== (executionContext & 4)) return null; + 0 !== (pendingPassiveEffectsLanes & 1) && + 0 !== root.tag && + flushPassiveEffects(); + flushSyncCallbacks(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { - if (90 !== pendingPassiveEffectsRenderPriority) { - var priorityLevel = - 97 < pendingPassiveEffectsRenderPriority - ? 97 - : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = 90; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); - } - return !1; -} -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function flushPassiveEffectsImpl() { - if (null === rootWithPendingPassiveEffects) return !1; - var root = rootWithPendingPassiveEffects, - lanes = pendingPassiveEffectsLanes; - rootWithPendingPassiveEffects = null; - pendingPassiveEffectsLanes = 0; - if (0 !== (executionContext & 48)) - throw Error("Cannot flush passive effects while already rendering."); - var prevExecutionContext = executionContext; - executionContext |= 32; - var prevInteractions = pushInteractions(root), - unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$96 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$96.destroy; - effect$96.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); - } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$96 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; + if (null !== rootWithPendingPassiveEffects) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), + prevTransition = ReactCurrentBatchConfig$2.transition, + previousPriority = currentUpdatePriority; try { - var create$100 = effect$96.create; - effect$96.destroy = create$100(); - } catch (error$101) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$101); + ReactCurrentBatchConfig$2.transition = 0; + currentUpdatePriority = 16 > renderPriority ? 16 : renderPriority; + if (null === rootWithPendingPassiveEffects) + var JSCompiler_inline_result = !1; + else { + renderPriority = rootWithPendingPassiveEffects; + rootWithPendingPassiveEffects = null; + pendingPassiveEffectsLanes = 0; + if (0 !== (executionContext & 24)) + throw Error("Cannot flush passive effects while already rendering."); + var prevExecutionContext = executionContext; + executionContext |= 16; + for (nextEffect = renderPriority.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + var sibling = fiber$jscomp$0.sibling, + returnFiber = fiber$jscomp$0.return; + if (fiber$jscomp$0 === fiberToDelete) { + detachFiberAfterEffects(fiber$jscomp$0); + nextEffect = null; + break; + } + if (null !== sibling) { + sibling.return = returnFiber; + nextEffect = sibling; + break; + } + nextEffect = returnFiber; + } + } + } + var previousFiber = fiber.alternate; + if (null !== previousFiber) { + var detachedChild = previousFiber.child; + if (null !== detachedChild) { + previousFiber.child = null; + do { + var detachedSibling = detachedChild.sibling; + detachedChild.sibling = null; + detachedChild = detachedSibling; + } while (null !== detachedChild); + } + } + nextEffect = fiber; + } + } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + b: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + var sibling$jscomp$0 = fiber.sibling; + if (null !== sibling$jscomp$0) { + sibling$jscomp$0.return = fiber.return; + nextEffect = sibling$jscomp$0; + break b; + } + nextEffect = fiber.return; + } + } + var finishedWork = renderPriority.current; + for (nextEffect = finishedWork; null !== nextEffect; ) { + child = nextEffect; + var firstChild = child.child; + if (0 !== (child.subtreeFlags & 1040) && null !== firstChild) + (firstChild.return = child), (nextEffect = firstChild); + else + b: for (child = finishedWork; null !== nextEffect; ) { + deletions = nextEffect; + if (0 !== (deletions.flags & 1024)) + try { + switch (deletions.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, deletions); + } + } catch (error) { + captureCommitPhaseError(deletions, deletions.return, error); + } + if (deletions === child) { + nextEffect = null; + break b; + } + var sibling$jscomp$1 = deletions.sibling; + if (null !== sibling$jscomp$1) { + sibling$jscomp$1.return = deletions.return; + nextEffect = sibling$jscomp$1; + break b; + } + nextEffect = deletions.return; + } + } + executionContext = prevExecutionContext; + flushSyncCallbacks(); + if ( + injectedHook && + "function" === typeof injectedHook.onPostCommitFiberRoot + ) + try { + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); + } catch (err) {} + JSCompiler_inline_result = !0; + } + return JSCompiler_inline_result; + } finally { + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$2.transition = prevTransition); } } - for (unmountEffects = root.current.firstEffect; null !== unmountEffects; ) - (create$100 = unmountEffects.nextEffect), - (unmountEffects.nextEffect = null), - unmountEffects.flags & 8 && - ((unmountEffects.sibling = null), (unmountEffects.stateNode = null)), - (unmountEffects = create$100); - tracing.__interactionsRef.current = prevInteractions; - finishPendingInteractions(root, lanes); - executionContext = prevExecutionContext; - flushSyncCallbackQueue(); - return !0; + return !1; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { sourceFiber = createCapturedValue(error, sourceFiber); @@ -6847,46 +7005,52 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { rootFiber = markUpdateLaneFromFiberToRoot(rootFiber, 1); null !== rootFiber && (markRootUpdated(rootFiber, 1, sourceFiber), - ensureRootIsScheduled(rootFiber, sourceFiber), - schedulePendingInteractions(rootFiber, 1)); + ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update), - schedulePendingInteractions(fiber, 1); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6898,34 +7062,28 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 130023424) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) : (workInProgressRootPingedLanes |= pingedLanes)); ensureRootIsScheduled(root, wakeable); - schedulePendingInteractions(root, pingedLanes); } function resolveRetryWakeable(boundaryFiber, wakeable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(wakeable); wakeable = 0; 0 === wakeable && - ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + (0 === (boundaryFiber.mode & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) - ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 130023424) && (nextRetryLane = 4194304))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && (markRootUpdated(boundaryFiber, wakeable, retryCache), - ensureRootIsScheduled(boundaryFiber, retryCache), - schedulePendingInteractions(boundaryFiber, wakeable)); + ensureRootIsScheduled(boundaryFiber, retryCache)); } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { @@ -6936,85 +7094,87 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateLanes; - break; - case 12: - 0 !== (renderLanes & workInProgress.childLanes) && - (workInProgress.flags |= 4); - updateLanes = workInProgress.stateNode; - updateLanes.effectDuration = 0; - updateLanes.passiveEffectDuration = 0; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, + if (0 === (renderLanes & updateLanes)) { + didReceiveUpdate = !1; + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer( workInProgress, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + break; + case 10: + updateLanes = workInProgress.type._context; + var nextValue = workInProgress.memoizedProps.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = nextValue; + break; + case 12: + 0 !== (renderLanes & workInProgress.childLanes) && + (workInProgress.flags |= 4); + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); + return null !== workInProgress ? workInProgress.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; + case 19: + updateLanes = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; + } + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); + } + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7026,22 +7186,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7051,21 +7211,13 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; - "function" === typeof getDerivedStateFromProps && - applyDerivedStateFromProps( - workInProgress, - updateLanes, - getDerivedStateFromProps, - current - ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7077,28 +7229,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7107,7 +7259,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7116,7 +7268,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7125,8 +7277,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7134,7 +7286,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7142,32 +7294,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7178,19 +7330,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7230,16 +7381,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7266,9 +7417,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 12: return ( (workInProgress.flags |= 4), - (updateLanes = workInProgress.stateNode), - (updateLanes.effectDuration = 0), - (updateLanes.passiveEffectDuration = 0), reconcileChildren( current, workInProgress, @@ -7280,27 +7428,15 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; - getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue2); - context$jscomp$0._currentValue2 = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + nextValue = workInProgress.pendingProps; + hasContext = workInProgress.memoizedProps; + var newValue = nextValue.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = newValue; + if (null !== hasContext) + if (objectIs(hasContext.value, newValue)) { if ( - getDerivedStateFromProps.children === context.children && + hasContext.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7312,76 +7448,71 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + newValue = workInProgress.child, + null !== newValue && (newValue.return = workInProgress); + null !== newValue; ) { - var list = context$jscomp$0.dependencies; + var list = newValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + hasContext = newValue.child; for ( var dependency = list.firstContext; null !== dependency; ) { - if ( - dependency.context === updateLanes && - 0 !== (dependency.observedBits & hasContext) - ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (dependency.context === updateLanes) { + if (1 === newValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = newValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + newValue.lanes |= renderLanes; + dependency = newValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(newValue.return, renderLanes); list.lanes |= renderLanes; break; } dependency = dependency.next; } } else - getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + hasContext = + 10 === newValue.tag + ? newValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; - if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + : newValue.child + : newValue.child; + if (null !== hasContext) hasContext.return = newValue; else - for ( - getDerivedStateFromProps = context$jscomp$0; - null !== getDerivedStateFromProps; - - ) { - if (getDerivedStateFromProps === workInProgress) { - getDerivedStateFromProps = null; + for (hasContext = newValue; null !== hasContext; ) { + if (hasContext === workInProgress) { + hasContext = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + newValue = hasContext.sibling; + if (null !== newValue) { + newValue.return = hasContext.return; + hasContext = newValue; break; } - getDerivedStateFromProps = getDerivedStateFromProps.return; + hasContext = hasContext.return; } - context$jscomp$0 = getDerivedStateFromProps; + newValue = hasContext; } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7389,28 +7520,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), - (hasContext = workInProgress.pendingProps), - (updateLanes = hasContext.children), + (nextValue = workInProgress.type), + (updateLanes = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7428,11 +7558,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7442,8 +7572,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7466,93 +7596,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { "). This error is likely caused by a bug in React. Please file an issue." ); }; -function markSpawnedWork(lane) { - null === spawnedWorkDuringRender - ? (spawnedWorkDuringRender = [lane]) - : spawnedWorkDuringRender.push(lane); -} -function scheduleInteractions(root, lane, interactions) { - if (0 < interactions.size) { - var pendingInteractionMap = root.pendingInteractionMap, - pendingInteractions = pendingInteractionMap.get(lane); - null != pendingInteractions - ? interactions.forEach(function(interaction) { - pendingInteractions.has(interaction) || interaction.__count++; - pendingInteractions.add(interaction); - }) - : (pendingInteractionMap.set(lane, new Set(interactions)), - interactions.forEach(function(interaction) { - interaction.__count++; - })); - pendingInteractionMap = tracing.__subscriberRef.current; - if (null !== pendingInteractionMap) - pendingInteractionMap.onWorkScheduled( - interactions, - 1e3 * lane + root.interactionThreadID - ); - } -} -function schedulePendingInteractions(root, lane) { - scheduleInteractions(root, lane, tracing.__interactionsRef.current); -} -function startWorkOnPendingInteractions(root, lanes) { - var interactions = new Set(); - root.pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledLane - ) { - 0 !== (lanes & scheduledLane) && - scheduledInteractions.forEach(function(interaction) { - return interactions.add(interaction); - }); - }); - root.memoizedInteractions = interactions; - if (0 < interactions.size) { - var subscriber = tracing.__subscriberRef.current; - if (null !== subscriber) { - root = 1e3 * lanes + root.interactionThreadID; - try { - subscriber.onWorkStarted(interactions, root); - } catch (error) { - scheduleCallback(99, function() { - throw error; - }); - } - } - } -} -function finishPendingInteractions(root, committedLanes) { - var remainingLanesAfterCommit = root.pendingLanes; - try { - var subscriber = tracing.__subscriberRef.current; - if (null !== subscriber && 0 < root.memoizedInteractions.size) - subscriber.onWorkStopped( - root.memoizedInteractions, - 1e3 * committedLanes + root.interactionThreadID - ); - } catch (error) { - scheduleCallback(99, function() { - throw error; - }); - } finally { - var pendingInteractionMap = root.pendingInteractionMap; - pendingInteractionMap.forEach(function(scheduledInteractions, lane) { - 0 === (remainingLanesAfterCommit & lane) && - (pendingInteractionMap.delete(lane), - scheduledInteractions.forEach(function(interaction) { - interaction.__count--; - if (null !== subscriber && 0 === interaction.__count) - try { - subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$102) { - scheduleCallback(99, function() { - throw error$102; - }); - } - })); - }); - } -} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -7562,8 +7605,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; this.actualDuration = 0; @@ -7604,11 +7647,11 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null), + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); + workInProgress.flags = current.flags & 1835008; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7645,17 +7688,16 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 4; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + mode |= 24; break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 2)), (type.elementType = REACT_PROFILER_TYPE), - (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), (type.stateNode = { effectDuration: 0, passiveEffectDuration: 0 }), type @@ -7663,7 +7705,6 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.lanes = lanes), type @@ -7760,9 +7801,6 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.expirationTimes = createLaneMap(-1); this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.expiredLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; this.entanglements = createLaneMap(0); - this.interactionThreadID = tracing.unstable_getThreadID(); - this.memoizedInteractions = new Set(); - this.pendingInteractionMap = new Map(); } function createPortal(children, containerInfo, implementation) { var key = @@ -7844,7 +7882,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7872,14 +7911,14 @@ batchedUpdatesImpl = function(fn, a) { (executionContext = prevExecutionContext), 0 === executionContext && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue()); + includesLegacySyncCallbacks && flushSyncCallbacks()); } }; var roots = new Map(), - devToolsConfig$jscomp$inline_887 = { + devToolsConfig$jscomp$inline_966 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.3-experimental-2d8d133e1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7894,11 +7933,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1087 = { - bundleType: devToolsConfig$jscomp$inline_887.bundleType, - version: devToolsConfig$jscomp$inline_887.version, - rendererPackageName: devToolsConfig$jscomp$inline_887.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_887.rendererConfig, +var internals$jscomp$inline_1208 = { + bundleType: devToolsConfig$jscomp$inline_966.bundleType, + version: devToolsConfig$jscomp$inline_966.version, + rendererPackageName: devToolsConfig$jscomp$inline_966.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_966.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7913,25 +7952,26 @@ var internals$jscomp$inline_1087 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_887.findFiberByHostInstance || + devToolsConfig$jscomp$inline_966.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, - getCurrentFiber: null + getCurrentFiber: null, + reconcilerVersion: "17.0.3-experimental-2d8d133e1" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1088 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1209 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1088.isDisabled && - hook$jscomp$inline_1088.supportsFiber + !hook$jscomp$inline_1209.isDisabled && + hook$jscomp$inline_1209.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1088.inject( - internals$jscomp$inline_1087 + (rendererID = hook$jscomp$inline_1209.inject( + internals$jscomp$inline_1208 )), - (injectedHook = hook$jscomp$inline_1088); + (injectedHook = hook$jscomp$inline_1209); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -7969,23 +8009,20 @@ exports.findHostInstance_DEPRECATED = function(componentOrHandle) { : componentOrHandle; }; exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { +exports.render = function(element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 8); - JSCompiler_inline_result = createFiber( - 3, - null, - null, - JSCompiler_inline_result - ); - root.current = JSCompiler_inline_result; - JSCompiler_inline_result.stateNode = root; - initializeUpdateQueue(JSCompiler_inline_result); - roots.set(containerTag, root); - } + root || + ((root = concurrentRoot ? 1 : 0), + (concurrentRoot = new FiberRootNode(containerTag, root, !1)), + (root = 1 === root ? 1 : 0), + isDevToolsPresent && (root |= 2), + (root = createFiber(3, null, null, root)), + (concurrentRoot.current = root), + (root.stateNode = concurrentRoot), + (root.memoizedState = { element: null }), + initializeUpdateQueue(root), + (root = concurrentRoot), + roots.set(containerTag, root)); updateContainer(element, root, null, callback); a: if (((element = root.current), element.child)) switch (element.child.tag) { @@ -7998,6 +8035,18 @@ exports.render = function(element, containerTag, callback) { else element = null; return element; }; +exports.sendAccessibilityEvent = function(handle, eventType) { + null != handle._nativeTag && + (handle._internalInstanceHandle + ? nativeFabricUIManager.sendAccessibilityEvent( + handle._internalInstanceHandle.stateNode.node, + eventType + ) + : ReactNativePrivateInterface.legacySendAccessibilityEvent( + handle._nativeTag, + eventType + )); +}; exports.stopSurface = function(containerTag) { var root = roots.get(containerTag); root && diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index c9d6478d841574..42a94f230c31dd 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<31b307087773581fd58a1b6ae0a24ae9>> + * @generated SignedSource<<2d7090219901967e7d2d5c87aacfd377>> */ 'use strict'; @@ -20,7 +20,6 @@ var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); var Scheduler = require("scheduler"); -var tracing = require("scheduler/tracing"); var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; @@ -380,6 +379,12 @@ function clearCaughtError() { } } +var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare + +function isArray(a) { + return isArrayImpl(a); +} + var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -407,13 +412,13 @@ var validateEventDispatches; validateEventDispatches = function(event) { var dispatchListeners = event._dispatchListeners; var dispatchInstances = event._dispatchInstances; - var listenersIsArr = Array.isArray(dispatchListeners); + var listenersIsArr = isArray(dispatchListeners); var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; - var instancesIsArr = Array.isArray(dispatchInstances); + var instancesIsArr = isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances @@ -450,7 +455,7 @@ function executeDispatchesInOrder(event) { validateEventDispatches(event); } - if (Array.isArray(dispatchListeners)) { + if (isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; @@ -481,7 +486,7 @@ function executeDispatchesInOrderStopAtTrueImpl(event) { validateEventDispatches(event); } - if (Array.isArray(dispatchListeners)) { + if (isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; @@ -527,7 +532,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners; var dispatchInstance = event._dispatchInstances; - if (!!Array.isArray(dispatchListener)) { + if (!!isArray(dispatchListener)) { throw Error("executeDirectDispatch(...): Invalid `event`."); } @@ -1154,11 +1159,11 @@ function accumulate(current, next) { } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { + if (isArray(current)) { return current.concat(next); } - if (Array.isArray(next)) { + if (isArray(next)) { return [current].concat(next); } @@ -1190,8 +1195,8 @@ function accumulateInto(current, next) { } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { - if (Array.isArray(next)) { + if (isArray(current)) { + if (isArray(next)) { current.push.apply(current, next); return current; } @@ -1200,7 +1205,7 @@ function accumulateInto(current, next) { return current; } - if (Array.isArray(next)) { + if (isArray(next)) { // A bit too dangerous to mutate `next`. return [current].concat(next); } @@ -2548,7 +2553,6 @@ function batchedUpdates(fn, bookkeeping) { function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, - _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; @@ -2923,11 +2927,16 @@ function getIteratorFn(maybeIterable) { } function getWrappedName(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + + if (displayName) { + return displayName; + } + var functionName = innerType.displayName || innerType.name || ""; - return ( - outerType.displayName || - (functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName) - ); + return functionName !== "" + ? wrapperName + "(" + functionName + ")" + : wrapperName; } // Keep in sync with react-reconciler/getComponentNameFromFiber function getContextName(type) { @@ -2943,7 +2952,7 @@ function getComponentNameFromType(type) { { if (typeof type.tag === "number") { error( - "Received an unexpected object in getComponentName(). " + + "Received an unexpected object in getComponentNameFromType(). " + "This is likely a bug in React. Please file an issue." ); } @@ -2994,7 +3003,13 @@ function getComponentNameFromType(type) { return getWrappedName(type, type.render, "ForwardRef"); case REACT_MEMO_TYPE: - return getComponentNameFromType(type.type); + var outerName = type.displayName || null; + + if (outerName !== null) { + return outerName; + } + + return getComponentNameFromType(type.type) || "Memo"; case REACT_LAZY_TYPE: { var lazyComponent = type; @@ -3120,7 +3135,7 @@ var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; var deferRenderPhaseUpdateToNextBatch = true; -var enableLazyContextPropagation = false; // Flow magic to verify the exports of this file match the original version. +var enableLazyContextPropagation = false; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -3189,9 +3204,24 @@ var ForceUpdateForLegacySuspense = // since we can defer traversing the tree during layout to look for Passive effects, // and instead rely on the static flag as a signal that there may be cleanup work. +var RefStatic = + /* */ + 262144; +var LayoutStatic = + /* */ + 524288; var PassiveStatic = /* */ - 262144; // These flags allow us to traverse to fibers that have effects on mount + 1048576; // These flags allow us to traverse to fibers that have effects on mount +// without traversing the entire tree after every commit for +// double invoking + +var MountLayoutDev = + /* */ + 2097152; +var MountPassiveDev = + /* */ + 4194304; // Groups of flags that are used in the commit phase to skip over trees that // don't contain effects, by checking subtreeFlags. var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity @@ -3211,7 +3241,7 @@ var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset // This allows certain concepts to persist without recalculting them, // e.g. whether a subtree contains passive effects or portals. -var StaticMask = PassiveStatic; +var StaticMask = LayoutStatic | PassiveStatic | RefStatic; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -3528,7 +3558,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) { + if (isArray(node)) { var i = node.length; while (i-- && removedKeyCount > 0) { @@ -3653,12 +3683,12 @@ function diffNestedProperty( return updatePayload; } - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) { + if (!isArray(prevProp) && !isArray(nextProp)) { // Both are leaves, we can diff the leaves. return diffProperties(updatePayload, prevProp, nextProp, validAttributes); } - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArray(prevProp) && isArray(nextProp)) { // Both are arrays, we can diff the arrays. return diffNestedArrayProperty( updatePayload, @@ -3668,7 +3698,7 @@ function diffNestedProperty( ); } - if (Array.isArray(prevProp)) { + if (isArray(prevProp)) { return diffProperties( updatePayload, // $FlowFixMe - We know that this is always an object when the input is. ReactNativePrivateInterface.flattenStyle(prevProp), // $FlowFixMe - We know that this isn't an array because of above flow. @@ -3695,7 +3725,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { return updatePayload; } - if (!Array.isArray(nextProp)) { + if (!isArray(nextProp)) { // Add each property of the leaf. return addProperties(updatePayload, nextProp, validAttributes); } @@ -3721,7 +3751,7 @@ function clearNestedProperty(updatePayload, prevProp, validAttributes) { return updatePayload; } - if (!Array.isArray(prevProp)) { + if (!isArray(prevProp)) { // Add each property of the leaf. return clearProperties(updatePayload, prevProp, validAttributes); } @@ -4093,6 +4123,186 @@ var ReactNativeFiberHostComponent = /*#__PURE__*/ (function() { return ReactNativeFiberHostComponent; })(); // eslint-disable-next-line no-unused-expressions +// This module only exists as an ESM wrapper around the external CommonJS +var scheduleCallback = Scheduler.unstable_scheduleCallback; +var cancelCallback = Scheduler.unstable_cancelCallback; +var shouldYield = Scheduler.unstable_shouldYield; +var requestPaint = Scheduler.unstable_requestPaint; +var now = Scheduler.unstable_now; +var ImmediatePriority = Scheduler.unstable_ImmediatePriority; +var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var NormalPriority = Scheduler.unstable_NormalPriority; +var IdlePriority = Scheduler.unstable_IdlePriority; + +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; + } + + 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) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. + + return true; + } + + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists + + return true; +} +function onScheduleRoot(root, children) { + { + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { + try { + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onCommitRoot(root, eventPriority) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; + + if (enableProfilerTimer) { + var schedulerPriority; + + switch (eventPriority) { + case DiscreteEventPriority: + schedulerPriority = ImmediatePriority; + break; + + case ContinuousEventPriority: + schedulerPriority = UserBlockingPriority; + break; + + case DefaultEventPriority: + schedulerPriority = NormalPriority; + break; + + case IdleEventPriority: + schedulerPriority = IdlePriority; + break; + + default: + schedulerPriority = NormalPriority; + break; + } + + injectedHook.onCommitFiberRoot( + rendererID, + root, + schedulerPriority, + didError + ); + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onPostCommitRoot(root) { + if ( + injectedHook && + typeof injectedHook.onPostCommitFiberRoot === "function" + ) { + try { + injectedHook.onPostCommitFiberRoot(rendererID, root); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} + +var NoMode = + /* */ + 0; // TODO: Remove ConcurrentMode by reading from the root tag instead + +var ConcurrentMode = + /* */ + 1; +var ProfileMode = + /* */ + 2; +var DebugTracingMode = + /* */ + 4; +var StrictLegacyMode = + /* */ + 8; +var StrictEffectsMode = + /* */ + 16; +var ConcurrentUpdatesByDefaultMode = + /* */ + 32; + // If those values are changed that package should be rebuilt and redeployed. var TotalLanes = 31; @@ -4106,7 +4316,7 @@ var SyncLane = /* */ 1; var InputContinuousHydrationLane = - /* */ + /* */ 2; var InputContinuousLane = /* */ @@ -4343,6 +4553,15 @@ function getNextLanes(root, wipLanes) { // Keep working on the existing in-progress tree. Do not interrupt. return wipLanes; } + } + + if ((root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode); + else if ((nextLanes & InputContinuousLane) !== NoLanes) { + // When updates are sync by default, we entangle continuous priority updates + // and default updates, so they render in the same batch. The only reason + // they use separate lanes is because continuous updates should interrupt + // transitions, but default updates should not. + nextLanes |= pendingLanes & DefaultLane; } // Check for entangled lanes and add them to the batch. // // A lane is said to be entangled with another when it's not allowed to render @@ -4436,12 +4655,19 @@ function computeExpirationTime(lane, currentTime) { case TransitionLane14: case TransitionLane15: case TransitionLane16: + return currentTime + 5000; + case RetryLane1: case RetryLane2: case RetryLane3: case RetryLane4: case RetryLane5: - return currentTime + 5000; + // TODO: Retries should be allowed to expire if they are CPU bound for + // too long, but when I made this change it caused a spike in browser + // crashes. There must be some other underlying bug; not super urgent but + // ideally should figure out why and fix it. Unfortunately we don't have + // a repro for the crashes, only detected via production metrics. + return NoTimestamp; case SelectiveHydrationLane: case IdleHydrationLane: @@ -4471,7 +4697,6 @@ function markStarvedLanesAsExpired(root, currentTime) { // it as expired to force it to finish. var lanes = pendingLanes; - var expiredLanes = 0; while (lanes > 0) { var index = pickArbitraryLaneIndex(lanes); @@ -4491,15 +4716,11 @@ function markStarvedLanesAsExpired(root, currentTime) { } } else if (expirationTime <= currentTime) { // This lane expired - expiredLanes |= lane; + root.expiredLanes |= lane; } lanes &= ~lane; } - - if (expiredLanes !== 0) { - markRootExpired(root, expiredLanes); - } } // This returns the highest priority pending lanes regardless of whether they function getLanesToRetrySynchronouslyOnError(root) { var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; @@ -4523,6 +4744,25 @@ function includesOnlyRetries(lanes) { function includesOnlyTransitions(lanes) { return (lanes & TransitionLanes) === lanes; } +function shouldTimeSlice(root, lanes) { + if ((lanes & root.expiredLanes) !== NoLanes) { + // At least one of these lanes expired. To prevent additional starvation, + // finish rendering without yielding execution. + return false; + } + + if ((root.current.mode & ConcurrentUpdatesByDefaultMode) !== NoMode) { + // Concurrent updates by default always use time slicing. + return true; + } + + var SyncDefaultLanes = + InputContinuousHydrationLane | + InputContinuousLane | + DefaultHydrationLane | + DefaultLane; + return (lanes & SyncDefaultLanes) === NoLanes; +} function isTransitionLane(lane) { return (lane & TransitionLanes) !== 0; } @@ -4641,18 +4881,6 @@ function markRootSuspended(root, suspendedLanes) { function markRootPinged(root, pingedLanes, eventTime) { root.pingedLanes |= root.suspendedLanes & pingedLanes; } -function markRootExpired(root, expiredLanes) { - var entanglements = root.entanglements; - var SyncLaneIndex = 0; - entanglements[SyncLaneIndex] |= expiredLanes; - root.entangledLanes |= SyncLane; - root.pendingLanes |= SyncLane; -} -function areLanesExpired(root, lanes) { - var SyncLaneIndex = 0; - var entanglements = root.entanglements; - return (entanglements[SyncLaneIndex] & lanes) !== NoLanes; -} function markRootMutableRead(root, updateLane) { root.mutableReadLanes |= updateLane & root.pendingLanes; } @@ -4662,6 +4890,7 @@ function markRootFinished(root, remainingLanes) { root.suspendedLanes = 0; root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; root.mutableReadLanes &= remainingLanes; root.entangledLanes &= remainingLanes; @@ -4740,6 +4969,9 @@ function setCurrentUpdatePriority(newPriority) { function higherEventPriority(a, b) { return a !== 0 && a < b ? a : b; } +function lowerEventPriority(a, b) { + return a === 0 || a > b ? a : b; +} function isHigherEventPriority(a, b) { return a !== 0 && a < b; } @@ -5360,6 +5592,8 @@ function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { return ""; } +var hasOwnProperty = Object.prototype.hasOwnProperty; + var loggedTypeFailures = {}; var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; @@ -5382,7 +5616,7 @@ function setCurrentlyValidatingElement(element) { function checkPropTypes(typeSpecs, values, location, componentName, element) { { // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); + var has = Function.call.bind(hasOwnProperty); for (var typeSpecName in typeSpecs) { if (has(typeSpecs, typeSpecName)) { @@ -5782,175 +6016,35 @@ function findCurrentUnmaskedContext(fiber) { var LegacyRoot = 0; var ConcurrentRoot = 1; -// This module only exists as an ESM wrapper around the external CommonJS -var scheduleCallback = Scheduler.unstable_scheduleCallback; -var cancelCallback = Scheduler.unstable_cancelCallback; -var shouldYield = Scheduler.unstable_shouldYield; -var requestPaint = Scheduler.unstable_requestPaint; -var now = Scheduler.unstable_now; -var ImmediatePriority = Scheduler.unstable_ImmediatePriority; -var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; -var NormalPriority = Scheduler.unstable_NormalPriority; -var IdlePriority = Scheduler.unstable_IdlePriority; - -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); +var syncQueue = null; +var includesLegacySyncCallbacks = false; +var isFlushingSyncQueue = false; +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]; + } else { + // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); } } - -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; - } - - 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) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. - - return true; - } - - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists - - return true; -} -function onScheduleRoot(root, children) { - { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } -} -function onCommitRoot(root, eventPriority) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; - - if (enableProfilerTimer) { - var schedulerPriority; - - switch (eventPriority) { - case DiscreteEventPriority: - schedulerPriority = ImmediatePriority; - break; - - case ContinuousEventPriority: - schedulerPriority = UserBlockingPriority; - break; - - case DefaultEventPriority: - schedulerPriority = NormalPriority; - break; - - case IdleEventPriority: - schedulerPriority = IdlePriority; - break; - - default: - schedulerPriority = NormalPriority; - break; - } - - injectedHook.onCommitFiberRoot( - rendererID, - root, - schedulerPriority, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } -} -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } -} - -var syncQueue = null; -var isFlushingSyncQueue = false; -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]; - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - syncQueue.push(callback); +function scheduleLegacySyncCallback(callback) { + includesLegacySyncCallbacks = true; + scheduleSyncCallback(callback); +} +function flushSyncCallbacksOnlyInLegacyMode() { + // Only flushes the queue if there's a legacy sync callback scheduled. + // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So + // it might make more sense for the queue to be a list of roots instead of a + // list of generic callbacks. Then we can have two: one for legacy roots, one + // for concurrent roots. And this method would only flush the legacy ones. + if (includesLegacySyncCallbacks) { + flushSyncCallbacks(); } } -function flushSyncCallbackQueue() { +function flushSyncCallbacks() { if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. isFlushingSyncQueue = true; @@ -5973,13 +6067,14 @@ function flushSyncCallbackQueue() { } syncQueue = null; + includesLegacySyncCallbacks = false; } catch (error) { // If something throws, leave the remaining callbacks on the queue. if (syncQueue !== null) { syncQueue = syncQueue.slice(i + 1); } // Resume flushing in the next tick - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue); + scheduleCallback(ImmediatePriority, flushSyncCallbacks); throw error; } finally { setCurrentUpdatePriority(previousUpdatePriority); @@ -6005,29 +6100,7 @@ var Passive$1 = /* */ 4; -// TODO: this is special because it gets imported during build. -// -// TODO: 17.0.3 has not been released to NPM; -// It exists as a placeholder so that DevTools can support work tag changes between releases. -// When we next publish a release (either 17.0.3 or 17.1.0), update the matching TODO in backend/renderer.js -var ReactVersion = "17.0.3"; - -var NoMode = - /* */ - 0; // TODO: Remove ConcurrentMode by reading from the root tag instead - -var ConcurrentMode = - /* */ - 1; -var ProfileMode = - /* */ - 2; -var DebugTracingMode = - /* */ - 4; -var StrictLegacyMode = - /* */ - 8; +var ReactVersion = "17.0.3-2d8d133e1"; var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = 0; @@ -6047,7 +6120,6 @@ function is(x, y) { var objectIs = typeof Object.is === "function" ? Object.is : is; -var hasOwnProperty = Object.prototype.hasOwnProperty; /** * Performs equality by iterating through keys on an object and returning false * when any key has values which are not strictly equal between the arguments. @@ -7295,7 +7367,11 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { ); var callback = update.callback; - if (callback !== null) { + if ( + callback !== null && // If the update was already committed, we should not queue its + // callback again. + update.lane !== NoLane + ) { workInProgress.flags |= Callback; var effects = queue.effects; @@ -7405,8 +7481,7 @@ function commitUpdateQueue(finishedWork, finishedQueue, instance) { } } -var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7524,6 +7599,7 @@ function applyDerivedStateFromProps( updateQueue.baseState = memoizedState; } } + var classComponentUpdater = { isMounted: isMounted, enqueueSetState: function(inst, payload, callback) { @@ -8173,7 +8249,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; @@ -8202,9 +8277,14 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; + var fiberFlags = Update; + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + // Never double-invoke effects for legacy roots. + fiberFlags |= MountLayoutDev; } + + workInProgress.flags |= fiberFlags; } } @@ -8266,9 +8346,14 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; + var fiberFlags = Update; + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + // Never double-invoke effects for legacy roots. + fiberFlags |= MountLayoutDev; } + + workInProgress.flags |= fiberFlags; } return false; @@ -8314,17 +8399,27 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; + var _fiberFlags = Update; + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + // Never double-invoke effects for legacy roots. + _fiberFlags |= MountLayoutDev; } + + workInProgress.flags |= _fiberFlags; } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; + var _fiberFlags2 = Update; + + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + // Never double-invoke effects for legacy roots. + _fiberFlags2 |= MountLayoutDev; } + + workInProgress.flags |= _fiberFlags2; } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8565,8 +8660,6 @@ var warnForMissingKey = function(child, returnFiber) {}; }; } -var isArray$1 = Array.isArray; - function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; @@ -8681,18 +8774,16 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { - if (returnFiber.type !== "textarea") { - var childString = Object.prototype.toString.call(newChild); + var childString = Object.prototype.toString.call(newChild); - { - throw Error( - "Objects are not valid as a React child (found: " + - (childString === "[object Object]" - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : childString) + - "). If you meant to render a collection of children, use an array instead." - ); - } + { + throw Error( + "Objects are not valid as a React child (found: " + + (childString === "[object Object]" + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : childString) + + "). If you meant to render a collection of children, use an array instead." + ); } } @@ -8948,7 +9039,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, @@ -9006,7 +9097,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -9061,7 +9152,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateFragment( @@ -9671,9 +9762,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild = newChild.props.children; } // Handle object types - var isObject = typeof newChild === "object" && newChild !== null; - - if (isObject) { + if (typeof newChild === "object" && newChild !== null) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return placeSingleChild( @@ -9695,6 +9784,26 @@ function ChildReconciler(shouldTrackSideEffects) { ) ); } + + if (isArray(newChild)) { + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + } + + if (getIteratorFn(newChild)) { + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); } if (typeof newChild === "string" || typeof newChild === "number") { @@ -9708,28 +9817,6 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray$1(newChild)) { - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - } - - if (getIteratorFn(newChild)) { - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - } - - if (isObject) { - throwOnInvalidObjectType(returnFiber, newChild); - } - { if (typeof newChild === "function") { warnOnFunctionType(returnFiber); @@ -10181,7 +10268,7 @@ function updateHookTypesDev() { function checkDepsAreArrayDev(deps) { { - if (deps !== undefined && deps !== null && !Array.isArray(deps)) { + if (deps !== undefined && deps !== null && !isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. error( @@ -10401,7 +10488,12 @@ function renderWithHooks( if ( current !== null && - (current.flags & PassiveStatic) !== (workInProgress.flags & PassiveStatic) + (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird + // and creates false positives. To make this work in legacy mode, we'd + // need to mark fibers that commit in an incomplete state, somehow. For + // now I'll disable the warning that most of the bugs that would trigger + // it are either exclusive to concurrent mode or exist in both. + (current.mode & ConcurrentMode) !== NoMode ) { error( "Internal React error: Expected static flag was missing. Please " + @@ -10424,7 +10516,14 @@ function bailoutHooks(current, workInProgress, lanes) { workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the // complete phase (bubbleProperties). - { + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) { + workInProgress.flags &= ~( + MountPassiveDev | + MountLayoutDev | + Passive | + Update + ); + } else { workInProgress.flags &= ~(Passive | Update); } @@ -11212,7 +11311,14 @@ function mountEffect(create, deps) { } } - { + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + return mountEffectImpl( + MountPassiveDev | Passive | PassiveStatic, + Passive$1, + create, + deps + ); + } else { return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); } } @@ -11229,9 +11335,13 @@ function updateEffect(create, deps) { } function mountLayoutEffect(create, deps) { - { - return mountEffectImpl(Update, Layout, create, deps); + var fiberFlags = Update; + + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + fiberFlags |= MountLayoutDev; } + + return mountEffectImpl(fiberFlags, Layout, create, deps); } function updateLayoutEffect(create, deps) { @@ -11283,15 +11393,18 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; + var fiberFlags = Update; - { - return mountEffectImpl( - Update, - Layout, - imperativeHandleEffect.bind(null, create, ref), - effectDeps - ); + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { + fiberFlags |= MountLayoutDev; } + + return mountEffectImpl( + fiberFlags, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); } function updateImperativeHandle(ref, create, deps) { @@ -11467,7 +11580,7 @@ function mountTransition() { var start = startTransition.bind(null, setPending); var hook = mountWorkInProgressHook(); hook.memoizedState = start; - return [start, isPending]; + return [isPending, start]; } function updateTransition() { @@ -11476,7 +11589,7 @@ function updateTransition() { var hook = updateWorkInProgressHook(); var start = hook.memoizedState; - return [start, isPending]; + return [isPending, start]; } function rerenderTransition() { @@ -11485,7 +11598,7 @@ function rerenderTransition() { var hook = updateWorkInProgressHook(); var start = hook.memoizedState; - return [start, isPending]; + return [isPending, start]; } var isUpdatingOpaqueValueInRenderPhase = false; @@ -12903,10 +13016,6 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { nextBaseLanes = renderLanes; } // Schedule this fiber to re-render at offscreen priority. Then bailout. - { - markSpawnedWork(OffscreenLane); - } - workInProgress.lanes = workInProgress.childLanes = laneToLanes( OffscreenLane ); @@ -13671,17 +13780,6 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); - } - adoptClassInstance(workInProgress, value); mountClassInstance(workInProgress, Component, props, renderLanes); return finishClassComponent( @@ -13953,11 +14051,6 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { // it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } - return _fallbackFragment; } else { return mountSuspensePrimaryChildren( @@ -14441,11 +14534,12 @@ function validateTailOptions(tailMode, revealOrder) { function validateSuspenseListNestedChild(childSlot, index) { { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + var isAnArray = isArray(childSlot); + var isIterable = + !isAnArray && typeof getIteratorFn(childSlot) === "function"; - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; error( "A nested %s was passed to row #%s in . Wrap it in " + @@ -14473,7 +14567,7 @@ function validateSuspenseListChildren(children, revealOrder) { children !== null && children !== false ) { - if (Array.isArray(children)) { + if (isArray(children)) { for (var i = 0; i < children.length; i++) { if (!validateSuspenseListNestedChild(children[i], i)) { return; @@ -15854,7 +15948,7 @@ function completeWork(current, workInProgress, renderLanes) { var _primaryChildFragment2 = workInProgress.child; if (_primaryChildFragment2 !== null) { - // $FlowFixMe Flow doens't support type casting in combiation with the -= operator + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator workInProgress.treeBaseDuration -= _primaryChildFragment2.treeBaseDuration; } @@ -15993,10 +16087,6 @@ function completeWork(current, workInProgress, renderLanes) { // since we're leaving it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } } } else { cutOffTailIfNeeded(renderState, false); @@ -16053,10 +16143,6 @@ function completeWork(current, workInProgress, renderLanes) { // since we're leaving it behind on this node. workInProgress.lanes = SomeRetryLane; - - { - markSpawnedWork(SomeRetryLane); - } } } @@ -16522,6 +16608,7 @@ function attachPingListener(root, wakeable, lanes) { // Memoize using the thread ID to prevent redundant listeners. threadIDs.add(lanes); var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); } } @@ -16755,10 +16842,9 @@ var didWarnAboutUndefinedSnapshotBeforeUpdate = null; { didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} - +} // Used during the commit phase to track the state of the Offscreen component stack. var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; -var nextEffect = null; +var nextEffect = null; // Used for Profiling builds to track updaters. var callComponentWillUnmountWithTimer = function(current, instance) { instance.props = current.memoizedProps; @@ -16767,7 +16853,7 @@ var callComponentWillUnmountWithTimer = function(current, instance) { { instance.componentWillUnmount(); } -}; // Capture errors so they don't interrupt unmounting. +}; // Capture errors so they don't interrupt mounting. function safelyCallComponentWillUnmount( current, @@ -16788,7 +16874,7 @@ function safelyCallComponentWillUnmount( captureCommitPhaseError(current, nearestMountedAncestor, unmountError); } } -} +} // Capture errors so they don't interrupt mounting. function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; @@ -17319,17 +17405,14 @@ function commitLayoutEffectOnFiber( var phase = current === null ? "mount" : "update"; if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - phase, - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime + ); } } @@ -17363,6 +17446,13 @@ function commitLayoutEffectOnFiber( } function hideOrUnhideAllChildren(finishedWork, isHidden) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (finishedWork.mode & ConcurrentMode) !== NoMode; + var current = finishedWork.alternate; + var wasHidden = current !== null && current.memoizedState !== null; // Only hide or unhide the top-most host nodes. + + var hostSubtreeRoot = null; + { // We only have the top Fiber that was inserted but we need to recurse down its // children to find all the terminal nodes. @@ -17370,20 +17460,25 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { while (true) { if (node.tag === HostComponent) { - var instance = node.stateNode; + if (hostSubtreeRoot === null) { + hostSubtreeRoot = node; + var instance = node.stateNode; - if (isHidden) { - hideInstance(instance); - } else { - unhideInstance(node.stateNode, node.memoizedProps); + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } } } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + if (hostSubtreeRoot === null) { + var _instance3 = node.stateNode; - if (isHidden) { - hideTextInstance(); - } else { - unhideTextInstance(_instance3, node.memoizedProps); + if (isHidden) { + hideTextInstance(); + } else { + unhideTextInstance(_instance3, node.memoizedProps); + } } } else if ( (node.tag === OffscreenComponent || @@ -17406,9 +17501,17 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { return; } + if (hostSubtreeRoot === node) { + hostSubtreeRoot = null; + } + node = node.return; } + if (hostSubtreeRoot === node) { + hostSubtreeRoot = null; + } + node.sibling.return = node.return; node = node.sibling; } @@ -17764,7 +17867,7 @@ function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { var isHost = tag === HostComponent || tag === HostText; if (isHost) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + var stateNode = node.stateNode; if (before) { insertInContainerBefore(parent); @@ -17792,7 +17895,7 @@ function insertOrAppendPlacementNode(node, before, parent) { var isHost = tag === HostComponent || tag === HostText; if (isHost) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + var stateNode = node.stateNode; if (before) { insertBefore(parent, stateNode, before); @@ -18075,13 +18178,8 @@ function attachSuspenseRetryListeners(finishedWork) { var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } - retryCache.add(wakeable); + wakeable.then(retry, retry); } }); @@ -18107,7 +18205,7 @@ function commitResetTextContent(current) { resetTextContent(current.stateNode); } -function commitMutationEffects(root, firstChild) { +function commitMutationEffects(root, firstChild, committedLanes) { nextEffect = firstChild; commitMutationEffects_begin(root); } @@ -18255,6 +18353,9 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { } function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; + while (nextEffect !== null) { var fiber = nextEffect; var firstChild = fiber.child; @@ -18269,6 +18370,9 @@ function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { } function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; + while (nextEffect !== null) { var fiber = nextEffect; @@ -18579,6 +18683,152 @@ function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { fiber.return = expectedReturnFiber; } +function invokeLayoutEffectMountInDEV(fiber) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + invokeGuardedCallback( + null, + commitHookEffectListMount, + null, + Layout | HasEffect, + fiber + ); + + if (hasCaughtError()) { + var mountError = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, mountError); + } + + break; + } + + case ClassComponent: { + var instance = fiber.stateNode; + invokeGuardedCallback(null, instance.componentDidMount, instance); + + if (hasCaughtError()) { + var _mountError = clearCaughtError(); + + captureCommitPhaseError(fiber, fiber.return, _mountError); + } + + break; + } + } + } +} + +function invokePassiveEffectMountInDEV(fiber) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + invokeGuardedCallback( + null, + commitHookEffectListMount, + null, + Passive$1 | HasEffect, + fiber + ); + + if (hasCaughtError()) { + var mountError = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, mountError); + } + + break; + } + } + } +} + +function invokeLayoutEffectUnmountInDEV(fiber) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + invokeGuardedCallback( + null, + commitHookEffectListUnmount, + null, + Layout | HasEffect, + fiber, + fiber.return + ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, unmountError); + } + + break; + } + + case ClassComponent: { + var instance = fiber.stateNode; + + if (typeof instance.componentWillUnmount === "function") { + invokeGuardedCallback( + null, + safelyCallComponentWillUnmount, + null, + fiber, + fiber.return, + instance + ); + + if (hasCaughtError()) { + var _unmountError = clearCaughtError(); + + captureCommitPhaseError(fiber, fiber.return, _unmountError); + } + } + + break; + } + } + } +} + +function invokePassiveEffectUnmountInDEV(fiber) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch (fiber.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + invokeGuardedCallback( + null, + commitHookEffectListUnmount, + null, + Passive$1 | HasEffect, + fiber, + fiber.return + ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, unmountError); + } + + break; + } + } + } +} + var COMPONENT_TYPE = 0; var HAS_PSEUDO_CLASS_TYPE = 1; var ROLE_TYPE = 2; @@ -18597,6 +18847,7 @@ if (typeof Symbol === "function" && Symbol.for) { var ceil = Math.ceil; var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ @@ -18685,13 +18936,7 @@ var NESTED_UPDATE_LIMIT = 50; var nestedUpdateCount = 0; var rootWithNestedUpdates = null; var NESTED_PASSIVE_UPDATE_LIMIT = 50; -var nestedPassiveUpdateCount = 0; // Marks the need to reschedule pending interactions at these lanes -// 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. -// TODO: Can use a bitmask instead of an array - -var spawnedWorkDuringRender = null; // If two updates are scheduled within the same event, we should treat their +var nestedPassiveUpdateCount = 0; // If two updates are scheduled within the same event, we should treat their // event times as simultaneous, even if the actual clock time has advanced // between the first and second call. @@ -18785,7 +19030,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (root === null) { warnAboutUpdateOnUnmountedFiberInDEV(fiber); return null; - } // Mark that the root has a pending update. + } markRootUpdated(root, lane, eventTime); @@ -18819,15 +19064,12 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { (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, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed + // 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. - performSyncWorkOnRoot(root); } else { ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, lane); if ( executionContext === NoContext && @@ -18839,13 +19081,12 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { // without immediately flushing it. We only do this for user-initiated // updates, to preserve historical behavior of legacy mode. resetRenderTimer(); - flushSyncCallbackQueue(); + flushSyncCallbacksOnlyInLegacyMode(); } } } else { // Schedule other updates after in case the callback is sync. ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, lane); } return root; @@ -18973,11 +19214,15 @@ function ensureRootIsScheduled(root, currentTime) { if (newCallbackPriority === SyncLane) { // Special case: Sync React callbacks are scheduled on a special // internal queue - scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + if (root.tag === LegacyRoot) { + scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else { + scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + } { // Flush the queue in an Immediate task. - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue); + scheduleCallback(ImmediatePriority, flushSyncCallbacks); } newCallbackNode = null; @@ -19051,20 +19296,17 @@ function performConcurrentWorkOnRoot(root, didTimeout) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; - } // TODO: We only check `didTimeout` defensively, to account for a Scheduler + } // We disable time-slicing in some cases: if the work has been CPU-bound + // for too long ("expired" work, to prevent starvation), or we're in + // sync-updates-by-default mode. + // TODO: We only check `didTimeout` defensively, to account for a Scheduler // bug we're still investigating. Once the bug in Scheduler is fixed, // we can remove this, since we track expiration ourselves. - if (didTimeout) { - // Something expired. Flush synchronously until there's no expired - // work left. - markRootExpired(root, lanes); // This will schedule a synchronous callback. - - ensureRootIsScheduled(root, now()); - return null; - } - - var exitStatus = renderRootConcurrent(root, lanes); + var exitStatus = + shouldTimeSlice(root, lanes) && !didTimeout + ? renderRootConcurrent(root, lanes) + : renderRootSync(root, lanes); if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { @@ -19084,10 +19326,11 @@ function performConcurrentWorkOnRoot(root, didTimeout) { // all pending updates are included. If it still fails after the second // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { - exitStatus = renderRootSync(root, lanes); + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = renderRootSync(root, errorRetryLanes); } } @@ -19252,22 +19495,16 @@ function performSyncWorkOnRoot(root) { } flushPassiveEffects(); - var lanes; - var exitStatus; + var lanes = getNextLanes(root, NoLanes); - if ( - root === workInProgressRoot && - areLanesExpired(root, workInProgressRootRenderLanes) - ) { - // There's a partial tree, and at least one of its lanes has expired. Finish - // rendering it before rendering the rest of the expired work. - lanes = workInProgressRootRenderLanes; - exitStatus = renderRootSync(root, lanes); - } else { - lanes = getNextLanes(root, NoLanes); - exitStatus = renderRootSync(root, lanes); + if (!includesSomeLane(lanes, SyncLane)) { + // There's no remaining sync work left. + ensureRootIsScheduled(root, now()); + return null; } + var exitStatus = renderRootSync(root, lanes); + if (root.tag !== LegacyRoot && exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. @@ -19285,9 +19522,10 @@ function performSyncWorkOnRoot(root) { // all pending updates are included. If it still fails after the second // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; exitStatus = renderRootSync(root, lanes); } } @@ -19309,7 +19547,7 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; -} // TODO: Do we still need this API? I think we can delete it. Was only used +} function batchedUpdates$1(fn, a) { var prevExecutionContext = executionContext; executionContext |= BatchedContext; @@ -19317,21 +19555,23 @@ function batchedUpdates$1(fn, a) { try { return fn(a); } finally { - executionContext = prevExecutionContext; + executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer + // most batchedUpdates-like method. if (executionContext === NoContext) { - // Flush the immediate callbacks that were scheduled during this batch resetRenderTimer(); - flushSyncCallbackQueue(); + flushSyncCallbacksOnlyInLegacyMode(); } } } function flushSync(fn, a) { var prevExecutionContext = executionContext; executionContext |= BatchedContext; + var prevTransition = ReactCurrentBatchConfig$2.transition; var previousPriority = getCurrentUpdatePriority(); try { + ReactCurrentBatchConfig$2.transition = 0; setCurrentUpdatePriority(DiscreteEventPriority); if (fn) { @@ -19341,12 +19581,13 @@ function flushSync(fn, a) { } } finally { setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; 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. if ((executionContext & (RenderContext | CommitContext)) === NoContext) { - flushSyncCallbackQueue(); + flushSyncCallbacks(); } else { { error( @@ -19403,10 +19644,6 @@ function prepareFreshStack(root, lanes) { workInProgressRootPingedLanes = NoLanes; enqueueInterleavedUpdates(); - { - spawnedWorkDuringRender = null; - } - { ReactStrictModeWarnings.discardPendingWarnings(); } @@ -19495,20 +19732,6 @@ function popDispatcher(prevDispatcher) { ReactCurrentDispatcher$2.current = prevDispatcher; } -function pushInteractions(root) { - { - var prevInteractions = tracing.__interactionsRef.current; - tracing.__interactionsRef.current = root.memoizedInteractions; - return prevInteractions; - } -} - -function popInteractions(prevInteractions) { - { - tracing.__interactionsRef.current = prevInteractions; - } -} - function markCommitTimeOfFallback() { globalMostRecentFallbackTime = now(); } @@ -19568,11 +19791,8 @@ function renderRootSync(root, lanes) { if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { prepareFreshStack(root, lanes); - startWorkOnPendingInteractions(root, lanes); } - var prevInteractions = pushInteractions(root); - do { try { workLoopSync(); @@ -19583,11 +19803,6 @@ function renderRootSync(root, lanes) { } while (true); resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - executionContext = prevExecutionContext; popDispatcher(prevDispatcher); @@ -19623,11 +19838,8 @@ function renderRootConcurrent(root, lanes) { if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { resetRenderTimer(); prepareFreshStack(root, lanes); - startWorkOnPendingInteractions(root, lanes); } - var prevInteractions = pushInteractions(root); - do { try { workLoopConcurrent(); @@ -19638,11 +19850,6 @@ function renderRootConcurrent(root, lanes) { } while (true); resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - popDispatcher(prevDispatcher); executionContext = prevExecutionContext; @@ -19786,11 +19993,14 @@ function commitRoot(root) { // TODO: This no longer makes any sense. We already wrap the mutation and // layout phases. Should be able to remove. var previousUpdateLanePriority = getCurrentUpdatePriority(); + var prevTransition = ReactCurrentBatchConfig$2.transition; try { + ReactCurrentBatchConfig$2.transition = 0; setCurrentUpdatePriority(DiscreteEventPriority); commitRootImpl(root, previousUpdateLanePriority); } finally { + ReactCurrentBatchConfig$2.transition = prevTransition; setCurrentUpdatePriority(previousUpdateLanePriority); } @@ -19819,6 +20029,15 @@ function commitRootImpl(root, renderPriorityLevel) { if (finishedWork === null) { return null; + } else { + { + if (lanes === NoLanes) { + error( + "root.finishedLanes should not be empty during a commit. This is a " + + "bug in React." + ); + } + } } root.finishedWork = null; @@ -19876,11 +20095,12 @@ function commitRootImpl(root, renderPriorityLevel) { NoFlags; if (subtreeHasEffects || rootHasEffect) { + var prevTransition = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; var previousPriority = getCurrentUpdatePriority(); setCurrentUpdatePriority(DiscreteEventPriority); var prevExecutionContext = executionContext; - executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles + executionContext |= CommitContext; // Reset this to null before calling lifecycles ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass // of the effect list for each phase: all mutation effects come before all @@ -19913,14 +20133,10 @@ function commitRootImpl(root, renderPriorityLevel) { // opportunity to paint. requestPaint(); - - { - popInteractions(prevInteractions); - } - executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value. setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; } else { // No effects. root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were @@ -19944,24 +20160,7 @@ function commitRootImpl(root, renderPriorityLevel) { remainingLanes = root.pendingLanes; // Check if there's remaining work on this root - if (remainingLanes !== NoLanes) { - { - if (spawnedWorkDuringRender !== null) { - var expirationTimes = spawnedWorkDuringRender; - spawnedWorkDuringRender = null; - - for (var i = 0; i < expirationTimes.length; i++) { - scheduleInteractions( - root, - expirationTimes[i], - root.memoizedInteractions - ); - } - } - - schedulePendingInteractions(root, remainingLanes); - } - } else { + if (remainingLanes === NoLanes) { // If there's no remaining work, we can clear the set of already failed // error boundaries. legacyErrorBoundariesThatAlreadyFailed = null; @@ -19969,11 +20168,7 @@ function commitRootImpl(root, renderPriorityLevel) { { 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, lanes); + commitDoubleInvokeEffectsInDEV(root.current, false); } } @@ -19997,9 +20192,9 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var error = firstUncaughtError; + var error$1 = firstUncaughtError; firstUncaughtError = null; - throw error; + throw error$1; } if ((executionContext & LegacyUnbatchedContext) !== NoContext) { @@ -20008,27 +20203,47 @@ function commitRootImpl(root, renderPriorityLevel) { // of the batch. return null; + } // If the passive effects are the result of a discrete render, flush them + // synchronously at the end of the current task so that the result is + // immediately observable. Otherwise, we assume that they are not + // order-dependent and do not need to be observed by external systems, so we + // can wait until after paint. + // TODO: We can optimize this by not scheduling the callback earlier. Since we + // currently schedule the callback in multiple places, will wait until those + // are consolidated. + + if ( + includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && + root.tag !== LegacyRoot + ) { + flushPassiveEffects(); } // If layout work was scheduled, flush it now. - flushSyncCallbackQueue(); + flushSyncCallbacks(); return null; } function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsLanes !== NoLanes) { - var priority = higherEventPriority( - DefaultEventPriority, - lanesToEventPriority(pendingPassiveEffectsLanes) - ); + // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should + // probably just combine the two functions. I believe they were only separate + // in the first place because we used to wrap it with + // `Scheduler.runWithPriority`, which accepts a function. But now we track the + // priority within React itself, so we can mutate the variable directly. + if (rootWithPendingPassiveEffects !== null) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes); + var priority = lowerEventPriority(DefaultEventPriority, renderPriority); + var prevTransition = ReactCurrentBatchConfig$2.transition; var previousPriority = getCurrentUpdatePriority(); try { + ReactCurrentBatchConfig$2.transition = 0; setCurrentUpdatePriority(priority); return flushPassiveEffectsImpl(); } finally { setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; } } @@ -20041,8 +20256,10 @@ function flushPassiveEffectsImpl() { } var root = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; - rootWithPendingPassiveEffects = null; + rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects. + // Figure out why and fix it. It's not causing any known issues (probably + // because it's only used for profiling), but it's a refactor hazard. + pendingPassiveEffectsLanes = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -20055,25 +20272,26 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); commitPassiveUnmountEffects(root.current); commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects { - popInteractions(prevInteractions); - finishPendingInteractions(root, lanes); + isFlushingPassiveEffects = false; } { - isFlushingPassiveEffects = false; + commitDoubleInvokeEffectsInDEV(root.current, true); } executionContext = prevExecutionContext; - flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this + flushSyncCallbacks(); // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. nestedPassiveUpdateCount = - rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; + rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; // TODO: Move to commitPassiveMountEffects + + onPostCommitRoot(root); + return true; } @@ -20110,7 +20328,6 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { if (root !== null) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, SyncLane); } } @@ -20150,7 +20367,6 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { if (root !== null) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, SyncLane); } return; @@ -20218,7 +20434,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { } ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, pingedLanes); } function retryTimedOutBoundary(boundaryFiber, retryLane) { @@ -20238,7 +20453,6 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { if (root !== null) { markRootUpdated(root, retryLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, retryLane); } } function resolveRetryWakeable(boundaryFiber, wakeable) { @@ -20319,6 +20533,63 @@ function flushRenderPhaseStrictModeWarningsInDEV() { } } +function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) { + { + // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects + // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level. + // Maybe not a big deal since this is DEV only behavior. + setCurrentFiber(fiber); + invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV); + + if (hasPassiveEffects) { + invokeEffectsInDev( + fiber, + MountPassiveDev, + invokePassiveEffectUnmountInDEV + ); + } + + invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV); + + if (hasPassiveEffects) { + invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV); + } + + resetCurrentFiber(); + } +} + +function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) { + { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + var current = firstChild; + var subtreeRoot = null; + + while (current !== null) { + var primarySubtreeFlag = current.subtreeFlags & fiberFlags; + + if ( + current !== subtreeRoot && + current.child !== null && + primarySubtreeFlag !== NoFlags + ) { + current = current.child; + } else { + if ((current.flags & fiberFlags) !== NoFlags) { + invokeEffectFn(current); + } + + if (current.sibling !== null) { + current = current.sibling; + } else { + current = subtreeRoot = current.return; + } + } + } + } +} + var didWarnStateUpdateForNotYetMountedComponent = null; function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { @@ -20725,144 +20996,6 @@ function warnIfUnmockedScheduler(fiber) { } } } -} - -function computeThreadID(root, lane) { - // Interaction threads are unique per root and expiration time. - // NOTE: Intentionally unsound cast. All that matters is that it's a number - // and it represents a batch of work. Could make a helper function instead, - // but meh this is fine for now. - return lane * 1000 + root.interactionThreadID; -} - -function markSpawnedWork(lane) { - if (spawnedWorkDuringRender === null) { - spawnedWorkDuringRender = [lane]; - } else { - spawnedWorkDuringRender.push(lane); - } -} - -function scheduleInteractions(root, lane, interactions) { - if (interactions.size > 0) { - var pendingInteractionMap = root.pendingInteractionMap; - var pendingInteractions = pendingInteractionMap.get(lane); - - 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(lane, 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, lane); - subscriber.onWorkScheduled(interactions, threadID); - } - } -} - -function schedulePendingInteractions(root, lane) { - scheduleInteractions(root, lane, tracing.__interactionsRef.current); -} - -function startWorkOnPendingInteractions(root, lanes) { - // 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, - scheduledLane - ) { - if (includesSomeLane(lanes, scheduledLane)) { - 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 performConcurrentWorkOnRoot() - // 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, lanes); - - 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, committedLanes) { - var remainingLanesAfterCommit = root.pendingLanes; - var subscriber; - - try { - subscriber = tracing.__subscriberRef.current; - - if (subscriber !== null && root.memoizedInteractions.size > 0) { - // FIXME: More than one lane can finish in a single commit. - var threadID = computeThreadID(root, committedLanes); - 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, lane) { - // 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 (!includesSomeLane(remainingLanesAfterCommit, lane)) { - pendingInteractionMap.delete(lane); - 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; - }); - } - } - }); - } - }); - } } // `act` testing API function shouldForceFlushFallbacksInDEV() { @@ -21607,21 +21740,32 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag, strictModeLevelOverride) { +function createHostRootFiber( + tag, + isStrictMode, + concurrentUpdatesByDefaultOverride +) { var mode; if (tag === ConcurrentRoot) { mode = ConcurrentMode; - if (strictModeLevelOverride !== null) { - if (strictModeLevelOverride >= 1) { - mode |= StrictLegacyMode; - } - } else { + if (isStrictMode === true) { + mode |= StrictLegacyMode; + { - mode |= StrictLegacyMode; + mode |= StrictEffectsMode; } } + + if ( + // We only use this flag for our repo tests to check both behaviors. + // TODO: Flip this flag and rename it something like "forceConcurrentByDefaultForTesting" + // Only for internal experiments. + concurrentUpdatesByDefaultOverride + ) { + mode |= ConcurrentUpdatesByDefaultMode; + } } else { mode = NoMode; } @@ -21672,16 +21816,8 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: - fiberTag = Mode; // Legacy strict mode ( without any level prop) defaults to level 1. - - var level = - pendingProps.unstable_level == null ? 1 : pendingProps.unstable_level; // Levels cascade; higher levels inherit all lower level modes. - // It is explicitly not supported to lower a mode with nesting, only to increase it. - - if (level >= 1) { - mode |= StrictLegacyMode; - } - + fiberTag = Mode; + mode |= StrictLegacyMode | StrictEffectsMode; break; case REACT_PROFILER_TYPE: @@ -21819,7 +21955,10 @@ function createFiberFromFragment(elements, mode, lanes, key) { function createFiberFromProfiler(pendingProps, mode, lanes, key) { { if (typeof pendingProps.id !== "string") { - error('Profiler must specify an "id" as a prop'); + error( + 'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', + typeof pendingProps.id + ); } } @@ -21946,17 +22085,12 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.pendingLanes = NoLanes; this.suspendedLanes = NoLanes; this.pingedLanes = NoLanes; + this.expiredLanes = NoLanes; this.mutableReadLanes = NoLanes; this.finishedLanes = NoLanes; this.entangledLanes = NoLanes; this.entanglements = createLaneMap(NoLanes); - { - this.interactionThreadID = tracing.unstable_getThreadID(); - this.memoizedInteractions = new Set(); - this.pendingInteractionMap = new Map(); - } - { switch (tag) { case ConcurrentRoot: @@ -21975,12 +22109,17 @@ function createFiberRoot( tag, hydrate, hydrationCallbacks, - strictModeLevelOverride + isStrictMode, + concurrentUpdatesByDefaultOverride ) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); + var uninitializedFiber = createHostRootFiber( + tag, + isStrictMode, + concurrentUpdatesByDefaultOverride + ); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; @@ -22118,14 +22257,16 @@ function createContainer( tag, hydrate, hydrationCallbacks, - strictModeLevelOverride + isStrictMode, + concurrentUpdatesByDefaultOverride ) { return createFiberRoot( containerInfo, tag, hydrate, hydrationCallbacks, - strictModeLevelOverride + isStrictMode, + concurrentUpdatesByDefaultOverride ); } function updateContainer(element, container, parentComponent, callback) { @@ -22234,10 +22375,10 @@ var setSuspenseHandler = null; { var copyWithDeleteImpl = function(obj, path, index) { var key = path[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); if (index + 1 === path.length) { - if (Array.isArray(updated)) { + if (isArray(updated)) { updated.splice(key, 1); } else { delete updated[key]; @@ -22256,14 +22397,14 @@ var setSuspenseHandler = null; var copyWithRenameImpl = function(obj, oldPath, newPath, index) { var oldKey = oldPath[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); if (index + 1 === oldPath.length) { var newKey = newPath[index]; // $FlowFixMe number or string is fine here updated[newKey] = updated[oldKey]; - if (Array.isArray(updated)) { + if (isArray(updated)) { updated.splice(oldKey, 1); } else { delete updated[oldKey]; @@ -22308,7 +22449,7 @@ var setSuspenseHandler = null; } var key = path[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); return updated; @@ -22465,7 +22606,10 @@ function injectIntoDevTools(devToolsConfig) { scheduleRoot: scheduleRoot, setRefreshHandler: setRefreshHandler, // Enables DevTools to append owner stacks to error messages in DEV mode. - getCurrentFiber: getCurrentFiberForDevTools + getCurrentFiber: getCurrentFiberForDevTools, + // Enables DevTools to detect reconciler version rather than renderer version + // which may not match for third party renderers. + reconcilerVersion: ReactVersion }); } @@ -22879,7 +23023,7 @@ function render(element, containerTag, callback) { if (!root) { // TODO (bvaughn): If we decide to keep the wrapper component, // We could create a wrapper for containerTag as well to reduce special casing. - root = createContainer(containerTag, LegacyRoot, false, null, null); + root = createContainer(containerTag, LegacyRoot, false, null, false, null); roots.set(containerTag, root); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index 33085b40dcd9ec..945ac922f5b3ea 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactNativeRenderer-dev * @preventMunge - * @generated + * @generated SignedSource<<6bb77061f5834486ffcc964f4e8c0fcf>> */ 'use strict'; @@ -21,7 +21,6 @@ var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); var Scheduler = require("scheduler"); -var tracing = require("scheduler/tracing"); var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; @@ -381,6 +380,12 @@ function clearCaughtError() { } } +var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare + +function isArray(a) { + return isArrayImpl(a); +} + var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -408,13 +413,13 @@ var validateEventDispatches; validateEventDispatches = function(event) { var dispatchListeners = event._dispatchListeners; var dispatchInstances = event._dispatchInstances; - var listenersIsArr = Array.isArray(dispatchListeners); + var listenersIsArr = isArray(dispatchListeners); var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; - var instancesIsArr = Array.isArray(dispatchInstances); + var instancesIsArr = isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances @@ -451,7 +456,7 @@ function executeDispatchesInOrder(event) { validateEventDispatches(event); } - if (Array.isArray(dispatchListeners)) { + if (isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; @@ -482,7 +487,7 @@ function executeDispatchesInOrderStopAtTrueImpl(event) { validateEventDispatches(event); } - if (Array.isArray(dispatchListeners)) { + if (isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; @@ -528,7 +533,7 @@ function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners; var dispatchInstance = event._dispatchInstances; - if (!!Array.isArray(dispatchListener)) { + if (!!isArray(dispatchListener)) { throw Error("executeDirectDispatch(...): Invalid `event`."); } @@ -1085,8 +1090,19 @@ function printTouchBank() { return printed; } +var instrumentationCallback; var ResponderTouchHistoryStore = { + /** + * Registers a listener which can be used to instrument every touch event. + */ + instrument: function(callback) { + instrumentationCallback = callback; + }, recordTouchTrack: function(topLevelType, nativeEvent) { + if (instrumentationCallback != null) { + instrumentationCallback(topLevelType, nativeEvent); + } + if (isMoveish(topLevelType)) { nativeEvent.changedTouches.forEach(recordTouchMove); } else if (isStartish(topLevelType)) { @@ -1144,11 +1160,11 @@ function accumulate(current, next) { } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { + if (isArray(current)) { return current.concat(next); } - if (Array.isArray(next)) { + if (isArray(next)) { return [current].concat(next); } @@ -1180,8 +1196,8 @@ function accumulateInto(current, next) { } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). - if (Array.isArray(current)) { - if (Array.isArray(next)) { + if (isArray(current)) { + if (isArray(next)) { current.push.apply(current, next); return current; } @@ -1190,7 +1206,7 @@ function accumulateInto(current, next) { return current; } - if (Array.isArray(next)) { + if (isArray(next)) { // A bit too dangerous to mutate `next`. return [current].concat(next); } @@ -1238,10 +1254,10 @@ var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; -var FundamentalComponent = 20; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; +var CacheComponent = 24; /** * Instance of element that should respond to touch/move types of interactions, @@ -2538,7 +2554,6 @@ function batchedUpdates(fn, bookkeeping) { function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, - _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; @@ -2865,12 +2880,12 @@ var REACT_SUSPENSE_TYPE = 0xead1; var REACT_SUSPENSE_LIST_TYPE = 0xead8; var REACT_MEMO_TYPE = 0xead3; var REACT_LAZY_TYPE = 0xead4; -var REACT_FUNDAMENTAL_TYPE = 0xead5; var REACT_SCOPE_TYPE = 0xead7; var REACT_OPAQUE_ID_TYPE = 0xeae0; var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; var REACT_OFFSCREEN_TYPE = 0xeae2; var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; +var REACT_CACHE_TYPE = 0xeae4; if (typeof Symbol === "function" && Symbol.for) { var symbolFor = Symbol.for; @@ -2886,12 +2901,12 @@ if (typeof Symbol === "function" && Symbol.for) { REACT_SUSPENSE_LIST_TYPE = symbolFor("react.suspense_list"); REACT_MEMO_TYPE = symbolFor("react.memo"); REACT_LAZY_TYPE = symbolFor("react.lazy"); - REACT_FUNDAMENTAL_TYPE = symbolFor("react.fundamental"); REACT_SCOPE_TYPE = symbolFor("react.scope"); REACT_OPAQUE_ID_TYPE = symbolFor("react.opaque.id"); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2913,18 +2928,23 @@ function getIteratorFn(maybeIterable) { } function getWrappedName(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + + if (displayName) { + return displayName; + } + var functionName = innerType.displayName || innerType.name || ""; - return ( - outerType.displayName || - (functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName) - ); -} + return functionName !== "" + ? wrapperName + "(" + functionName + ")" + : wrapperName; +} // Keep in sync with react-reconciler/getComponentNameFromFiber function getContextName(type) { return type.displayName || "Context"; -} +} // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. -function getComponentName(type) { +function getComponentNameFromType(type) { if (type == null) { // Host root, text node or just invalid type. return null; @@ -2933,7 +2953,7 @@ function getComponentName(type) { { if (typeof type.tag === "number") { error( - "Received an unexpected object in getComponentName(). " + + "Received an unexpected object in getComponentNameFromType(). " + "This is likely a bug in React. Please file an issue." ); } @@ -2965,6 +2985,9 @@ function getComponentName(type) { case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + + case REACT_CACHE_TYPE: + return "Cache"; } if (typeof type === "object") { @@ -2981,7 +3004,13 @@ function getComponentName(type) { return getWrappedName(type, type.render, "ForwardRef"); case REACT_MEMO_TYPE: - return getComponentName(type.type); + var outerName = type.displayName || null; + + if (outerName !== null) { + return outerName; + } + + return getComponentNameFromType(type.type) || "Memo"; case REACT_LAZY_TYPE: { var lazyComponent = type; @@ -2989,7 +3018,7 @@ function getComponentName(type) { var init = lazyComponent._init; try { - return getComponentName(init(payload)); + return getComponentNameFromType(init(payload)); } catch (x) { return null; } @@ -3000,10 +3029,113 @@ function getComponentName(type) { return null; } +function getWrappedName$1(outerType, innerType, wrapperName) { + var functionName = innerType.displayName || innerType.name || ""; + return ( + outerType.displayName || + (functionName !== "" ? wrapperName + "(" + functionName + ")" : wrapperName) + ); +} // Keep in sync with shared/getComponentNameFromType + +function getContextName$1(type) { + return type.displayName || "Context"; +} + +function getComponentNameFromFiber(fiber) { + var tag = fiber.tag, + type = fiber.type; + + switch (tag) { + case CacheComponent: + return "Cache"; + + case ContextConsumer: + var context = type; + return getContextName$1(context) + ".Consumer"; + + case ContextProvider: + var provider = type; + return getContextName$1(provider._context) + ".Provider"; + + case DehydratedFragment: + return "DehydratedFragment"; + + case ForwardRef: + return getWrappedName$1(type, type.render, "ForwardRef"); + + case Fragment: + return "Fragment"; + + case HostComponent: + // Host component type is the display name (e.g. "div", "View") + return type; + + case HostPortal: + return "Portal"; + + case HostRoot: + return "Root"; + + case HostText: + return "Text"; + + case LazyComponent: + // Name comes from the type in this case; we don't have a tag. + return getComponentNameFromType(type); + + case LegacyHiddenComponent: + return "LegacyHidden"; + + case Mode: + if (type === REACT_STRICT_MODE_TYPE) { + // Don't be less specific than shared/getComponentNameFromType + return "StrictMode"; + } + + return "Mode"; + + case OffscreenComponent: + return "Offscreen"; + + case Profiler: + return "Profiler"; + + case ScopeComponent: + return "Scope"; + + case SuspenseComponent: + return "Suspense"; + + case SuspenseListComponent: + return "SuspenseList"; + // The display name for this tags come from the user-provided type: + + case ClassComponent: + case FunctionComponent: + case IncompleteClassComponent: + case IndeterminateComponent: + case MemoComponent: + case SimpleMemoComponent: + if (typeof type === "function") { + return type.displayName || type.name || null; + } + + if (typeof type === "string") { + return type; + } + + break; + } + + return null; +} + var enableProfilerTimer = true; -var enableFundamentalAPI = false; +var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; +var deferRenderPhaseUpdateToNextBatch = true; +var enableLazyContextPropagation = false; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -3021,53 +3153,86 @@ var Update = 4; var PlacementAndUpdate = /* */ - 6; -var Deletion = - /* */ - 8; + Placement | Update; +var ChildDeletion = + /* */ + 16; var ContentReset = /* */ - 16; + 32; var Callback = /* */ - 32; + 64; var DidCapture = /* */ - 64; + 128; var Ref = /* */ - 128; + 256; var Snapshot = /* */ - 256; + 512; var Passive = /* */ - 512; + 1024; var Hydrating = /* */ - 1024; + 2048; var HydratingAndUpdate = /* */ - 1028; + Hydrating | Update; +var Visibility = + /* */ + 4096; var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ - 4095; // These are not really side effects, but we still reuse this field. + 8191; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ - 4096; + 8192; var ShouldCapture = /* */ - 8192; // TODO (effects) Remove this bit once the new reconciler is synced to the old. - -var PassiveUnmountPendingDev = - /* */ 16384; var ForceUpdateForLegacySuspense = /* */ - 32768; // Static tags describe aspects of a fiber that are not specific to a render, + 32768; +// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). +// This enables us to defer more work in the unmount case, +// since we can defer traversing the tree during layout to look for Passive effects, +// and instead rely on the static flag as a signal that there may be cleanup work. + +var RefStatic = + /* */ + 262144; +var LayoutStatic = + /* */ + 524288; +var PassiveStatic = + /* */ + 1048576; // These flags allow us to traverse to fibers that have effects on mount +// don't contain effects, by checking subtreeFlags. + +var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity + // flag logic (see #20043) + Update | Snapshot | 0; +var MutationMask = + Placement | + Update | + ChildDeletion | + ContentReset | + Ref | + Hydrating | + Visibility; +var LayoutMask = Update | Callback | Ref; // TODO: Split into PassiveMountMask and PassiveUnmountMask + +var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. +// This allows certain concepts to persist without recalculting them, +// e.g. whether a subtree contains passive effects or portals. + +var StaticMask = LayoutStatic | PassiveStatic | RefStatic; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -3124,7 +3289,7 @@ function isMounted(component) { "never access something that requires stale data from the previous " + "render, such as refs. Move this logic to componentDidMount and " + "componentDidUpdate instead.", - getComponentName(ownerFiber.type) || "A component" + getComponentNameFromFiber(ownerFiber) || "A component" ); } @@ -3307,38 +3472,28 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null + ? findCurrentHostFiberImpl(currentParent) + : null; +} - if (!currentParent) { - return null; - } // Next we'll drill down this component to find the first HostComponent/Text. - - var node = currentParent; - - while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - return node; - } else if (node.child) { - node.child.return = node; - node = node.child; - continue; - } +function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } - if (node === currentParent) { - return null; - } + var child = node.child; - while (!node.sibling) { - if (!node.return || node.return === currentParent) { - return null; - } + while (child !== null) { + var match = findCurrentHostFiberImpl(child); - node = node.return; + if (match !== null) { + return match; } - node.sibling.return = node.return; - node = node.sibling; - } // Flow needs the return null here, but ESLint complains about it. - // eslint-disable-next-line no-unreachable + child = child.sibling; + } return null; } @@ -3394,7 +3549,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) { + if (isArray(node)) { var i = node.length; while (i-- && removedKeyCount > 0) { @@ -3519,12 +3674,12 @@ function diffNestedProperty( return updatePayload; } - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) { + if (!isArray(prevProp) && !isArray(nextProp)) { // Both are leaves, we can diff the leaves. return diffProperties(updatePayload, prevProp, nextProp, validAttributes); } - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArray(prevProp) && isArray(nextProp)) { // Both are arrays, we can diff the arrays. return diffNestedArrayProperty( updatePayload, @@ -3534,7 +3689,7 @@ function diffNestedProperty( ); } - if (Array.isArray(prevProp)) { + if (isArray(prevProp)) { return diffProperties( updatePayload, // $FlowFixMe - We know that this is always an object when the input is. ReactNativePrivateInterface.flattenStyle(prevProp), // $FlowFixMe - We know that this isn't an array because of above flow. @@ -3561,7 +3716,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { return updatePayload; } - if (!Array.isArray(nextProp)) { + if (!isArray(nextProp)) { // Add each property of the leaf. return addProperties(updatePayload, nextProp, validAttributes); } @@ -3587,7 +3742,7 @@ function clearNestedProperty(updatePayload, prevProp, validAttributes) { return updatePayload; } - if (!Array.isArray(prevProp)) { + if (!isArray(prevProp)) { // Add each property of the leaf. return clearProperties(updatePayload, prevProp, validAttributes); } @@ -3959,1978 +4114,1878 @@ var ReactNativeFiberHostComponent = /*#__PURE__*/ (function() { return ReactNativeFiberHostComponent; })(); // eslint-disable-next-line no-unused-expressions -// can re-export everything from this module. +// This module only exists as an ESM wrapper around the external CommonJS +var scheduleCallback = Scheduler.unstable_scheduleCallback; +var cancelCallback = Scheduler.unstable_cancelCallback; +var shouldYield = Scheduler.unstable_shouldYield; +var requestPaint = Scheduler.unstable_requestPaint; +var now = Scheduler.unstable_now; +var ImmediatePriority = Scheduler.unstable_ImmediatePriority; +var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var NormalPriority = Scheduler.unstable_NormalPriority; +var IdlePriority = Scheduler.unstable_IdlePriority; -function shim() { - { - throw Error( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." - ); +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; } -} // Hydration (when unsupported) -var isSuspenseInstancePending = shim; -var isSuspenseInstanceFallback = shim; -var hydrateTextInstance = shim; - -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; -var UPDATE_SIGNAL = {}; -{ - Object.freeze(UPDATE_SIGNAL); -} // Counter for uniquely identifying views. -// % 10 === 1 means it is a rootTag. -// % 2 === 0 means it is a Fabric tag. + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; -var nextReactTag = 3; + 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; + } -function allocateTag() { - var tag = nextReactTag; + if (!hook.supportsFiber) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. - if (tag % 10 === 1) { - tag += 2; + return true; } - nextReactTag = tag + 2; - return tag; -} + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. -function recursivelyUncacheFiberNode(node) { - if (typeof node === "number") { - // Leaf node (eg text) - uncacheFiberNode(node); - } else { - uncacheFiberNode(node._nativeTag); + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists - node._children.forEach(recursivelyUncacheFiberNode); - } -} -function appendInitialChild(parentInstance, child) { - parentInstance._children.push(child); + return true; } -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = allocateTag(); - var viewConfig = getViewConfigForType(type); - +function onScheduleRoot(root, children) { { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { + try { + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } } +} +function onCommitRoot(root, eventPriority) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; - var updatePayload = create(props, viewConfig.validAttributes); - ReactNativePrivateInterface.UIManager.createView( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload // props - ); - var component = new ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandle - ); - precacheFiberNode(internalInstanceHandle, tag); - updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined - // in the same file but if it's external it can't see the types. + if (enableProfilerTimer) { + var schedulerPriority; - return component; -} -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - if (!hostContext.isInAParentText) { - throw Error("Text strings must be rendered within a component."); - } + switch (eventPriority) { + case DiscreteEventPriority: + schedulerPriority = ImmediatePriority; + break; - var tag = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { - text: text - } // props - ); - precacheFiberNode(internalInstanceHandle, tag); - return tag; -} -function finalizeInitialChildren( - parentInstance, - type, - props, - rootContainerInstance, - hostContext -) { - // Don't send a no-op message over the bridge. - if (parentInstance._children.length === 0) { - return false; - } // Map from child objects to native tags. - // Either way we need to pass a copy of the Array to prevent it from being frozen. + case ContinuousEventPriority: + schedulerPriority = UserBlockingPriority; + break; - var nativeTags = parentInstance._children.map(function(child) { - return typeof child === "number" - ? child // Leaf node (eg text) - : child._nativeTag; - }); + case DefaultEventPriority: + schedulerPriority = NormalPriority; + break; - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance._nativeTag, // containerTag - nativeTags // reactTags - ); - return false; -} -function getRootHostContext(rootContainerInstance) { - return { - isInAParentText: false - }; -} -function getChildHostContext(parentHostContext, type, rootContainerInstance) { - var prevIsInAParentText = parentHostContext.isInAParentText; - var isInAParentText = - type === "AndroidTextInput" || // Android - type === "RCTMultilineTextInputView" || // iOS - type === "RCTSinglelineTextInputView" || // iOS - type === "RCTText" || - type === "RCTVirtualText"; + case IdleEventPriority: + schedulerPriority = IdlePriority; + break; - if (prevIsInAParentText !== isInAParentText) { - return { - isInAParentText: isInAParentText - }; - } else { - return parentHostContext; + default: + schedulerPriority = NormalPriority; + break; + } + + injectedHook.onCommitFiberRoot( + rendererID, + root, + schedulerPriority, + didError + ); + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } } } -function getPublicInstance(instance) { - return instance; -} -function prepareForCommit(containerInfo) { - // Noop - return null; -} -function prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - hostContext -) { - return UPDATE_SIGNAL; -} -function resetAfterCommit(containerInfo) { - // Noop -} -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; -function shouldSetTextContent(type, props) { - // TODO (bvaughn) Revisit this decision. - // Always returning false simplifies the createInstance() implementation, - // But creates an additional child Fiber for raw text children. - // No additional native views are created though. - // It's not clear to me which is better so I'm deferring for now. - // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 - return false; -} // ------------------- -function appendChild(parentInstance, child) { - var childTag = typeof child === "number" ? child : child._nativeTag; - var children = parentInstance._children; - var index = children.indexOf(child); +function onPostCommitRoot(root) { + if ( + injectedHook && + typeof injectedHook.onPostCommitFiberRoot === "function" + ) { + try { + injectedHook.onPostCommitFiberRoot(rendererID, root); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; - if (index >= 0) { - children.splice(index, 1); - children.push(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerTag - [index], // moveFromIndices - [children.length - 1], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [] // removeAtIndices - ); - } else { - children.push(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerTag - [], // moveFromIndices - [], // moveToIndices - [childTag], // addChildReactTags - [children.length - 1], // addAtIndices - [] // removeAtIndices - ); + error("React instrumentation encountered an error: %s", err); + } + } + } } } -function appendChildToContainer(parentInstance, child) { - var childTag = typeof child === "number" ? child : child._nativeTag; - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance, // containerTag - [childTag] // reactTags - ); -} -function commitTextUpdate(textInstance, oldText, newText) { - ReactNativePrivateInterface.UIManager.updateView( - textInstance, // reactTag - "RCTRawText", // viewName - { - text: newText - } // props - ); -} -function commitUpdate( - instance, - updatePayloadTODO, - type, - oldProps, - newProps, - internalInstanceHandle -) { - var viewConfig = instance.viewConfig; - updateFiberProps(instance._nativeTag, newProps); - var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. - // This is an expensive no-op for Android, and causes an unnecessary - // view invalidation for certain components (eg RCTTextInput) on iOS. +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; - if (updatePayload != null) { - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, // reactTag - viewConfig.uiViewClassName, // viewName - updatePayload // props - ); + error("React instrumentation encountered an error: %s", err); + } + } + } } } -function insertBefore(parentInstance, child, beforeChild) { - var children = parentInstance._children; - var index = children.indexOf(child); // Move existing child or add new child? - if (index >= 0) { - children.splice(index, 1); - var beforeChildIndex = children.indexOf(beforeChild); - children.splice(beforeChildIndex, 0, child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [index], // moveFromIndices - [beforeChildIndex], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [] // removeAtIndices - ); - } else { - var _beforeChildIndex = children.indexOf(beforeChild); +var NoMode = + /* */ + 0; // TODO: Remove ConcurrentMode by reading from the root tag instead - children.splice(_beforeChildIndex, 0, child); - var childTag = typeof child === "number" ? child : child._nativeTag; - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [], // moveFromIndices - [], // moveToIndices - [childTag], // addChildReactTags - [_beforeChildIndex], // addAtIndices - [] // removeAtIndices - ); - } -} -function insertInContainerBefore(parentInstance, child, beforeChild) { - // TODO (bvaughn): Remove this check when... - // We create a wrapper object for the container in ReactNative render() - // Or we refactor to remove wrapper objects entirely. - // For more info on pros/cons see PR #8560 description. - if (!(typeof parentInstance !== "number")) { - throw Error("Container does not support insertBefore operation"); - } -} -function removeChild(parentInstance, child) { - recursivelyUncacheFiberNode(child); - var children = parentInstance._children; - var index = children.indexOf(child); - children.splice(index, 1); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [], // moveFromIndices - [], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [index] // removeAtIndices - ); -} -function removeChildFromContainer(parentInstance, child) { - recursivelyUncacheFiberNode(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance, // containerID - [], // moveFromIndices - [], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [0] // removeAtIndices - ); -} -function resetTextContent(instance) { - // Noop -} -function hideInstance(instance) { - var viewConfig = instance.viewConfig; - var updatePayload = create( - { - style: { - display: "none" - } - }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -function hideTextInstance(textInstance) { - throw new Error("Not yet implemented."); -} -function unhideInstance(instance, props) { - var viewConfig = instance.viewConfig; - var updatePayload = diff( - Object.assign({}, props, { - style: [ - props.style, - { - display: "none" - } - ] - }), - props, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -function clearContainer(container) { - // TODO Implement this for React Native - // UIManager does not expose a "remove all" type method. -} -function unhideTextInstance(textInstance, text) { - throw new Error("Not yet implemented."); -} -function makeClientIdInDEV(warnOnAccessInDEV) { - throw new Error("Not yet implemented"); -} -function preparePortalMount(portalInstance) { - // noop -} - -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -function describeBuiltInComponentFrame(name, source, ownerFn) { - { - var ownerName = null; - - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } - - return describeComponentFrame(name, source, ownerName); - } -} -var componentFrameCache; - -{ - var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap(); -} -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +var ConcurrentMode = + /* */ + 1; +var ProfileMode = + /* */ + 2; +var DebugTracingMode = + /* */ + 4; +var StrictLegacyMode = + /* */ + 8; +var StrictEffectsMode = + /* */ + 16; -function describeComponentFrame(name, source, ownerName) { - var sourceInfo = ""; +// If those values are changed that package should be rebuilt and redeployed. - if (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: - // prefer "folder/index.js" instead of just "index.js". +var TotalLanes = 31; +var NoLanes = + /* */ + 0; +var NoLane = + /* */ + 0; +var SyncLane = + /* */ + 1; +var InputContinuousHydrationLane = + /* */ + 2; +var InputContinuousLane = + /* */ + 4; +var DefaultHydrationLane = + /* */ + 8; +var DefaultLane = + /* */ + 16; +var TransitionHydrationLane = + /* */ + 32; +var TransitionLanes = + /* */ + 4194240; +var TransitionLane1 = + /* */ + 64; +var TransitionLane2 = + /* */ + 128; +var TransitionLane3 = + /* */ + 256; +var TransitionLane4 = + /* */ + 512; +var TransitionLane5 = + /* */ + 1024; +var TransitionLane6 = + /* */ + 2048; +var TransitionLane7 = + /* */ + 4096; +var TransitionLane8 = + /* */ + 8192; +var TransitionLane9 = + /* */ + 16384; +var TransitionLane10 = + /* */ + 32768; +var TransitionLane11 = + /* */ + 65536; +var TransitionLane12 = + /* */ + 131072; +var TransitionLane13 = + /* */ + 262144; +var TransitionLane14 = + /* */ + 524288; +var TransitionLane15 = + /* */ + 1048576; +var TransitionLane16 = + /* */ + 2097152; +var RetryLanes = + /* */ + 130023424; +var RetryLane1 = + /* */ + 4194304; +var RetryLane2 = + /* */ + 8388608; +var RetryLane3 = + /* */ + 16777216; +var RetryLane4 = + /* */ + 33554432; +var RetryLane5 = + /* */ + 67108864; +var SomeRetryLane = RetryLane1; +var SelectiveHydrationLane = + /* */ + 134217728; +var NonIdleLanes = + /* */ + 268435455; +var IdleHydrationLane = + /* */ + 268435456; +var IdleLane = + /* */ + 536870912; +var OffscreenLane = + /* */ + 1073741824; // This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler) +var NoTimestamp = -1; +var nextTransitionLane = TransitionLane1; +var nextRetryLane = RetryLane1; - if (/^index\./.test(fileName)) { - var match = path.match(BEFORE_SLASH_RE); +function getHighestPriorityLanes(lanes) { + switch (getHighestPriorityLane(lanes)) { + case SyncLane: + return SyncLane; - if (match) { - var pathBeforeSlash = match[1]; + case InputContinuousHydrationLane: + return InputContinuousHydrationLane; + + case InputContinuousLane: + return InputContinuousLane; + + case DefaultHydrationLane: + return DefaultHydrationLane; + + case DefaultLane: + return DefaultLane; + + case TransitionHydrationLane: + return TransitionHydrationLane; + + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + case TransitionLane15: + case TransitionLane16: + return lanes & TransitionLanes; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + case RetryLane5: + return lanes & RetryLanes; + + case SelectiveHydrationLane: + return SelectiveHydrationLane; + + case IdleHydrationLane: + return IdleHydrationLane; + + case IdleLane: + return IdleLane; + + case OffscreenLane: + return OffscreenLane; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } - } - } + default: + { + error("Should have found matching lanes. This is a bug in React."); + } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; + return lanes; } - - return "\n in " + (name || "Unknown") + sourceInfo; } -function describeClassComponentFrame(ctor, source, ownerFn) { - { - return describeFunctionComponentFrame(ctor, source, ownerFn); +function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; + + if (pendingLanes === NoLanes) { + return NoLanes; } -} -function describeFunctionComponentFrame(fn, source, ownerFn) { - { - if (!fn) { - return ""; - } - var name = fn.displayName || fn.name || null; - var ownerName = null; + var nextLanes = NoLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished, + // even if the work is suspended. - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - return describeComponentFrame(name, source, ownerName); - } -} + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; -function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { - if (type == null) { - return ""; - } + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; - if (typeof type === "function") { - { - return describeFunctionComponentFrame(type, source, ownerFn); + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); + } } - } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; - if (typeof type === "string") { - return describeBuiltInComponentFrame(type, source, ownerFn); + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + } + } } - switch (type) { - case REACT_SUSPENSE_TYPE: - return describeBuiltInComponentFrame("Suspense", source, ownerFn); + if (nextLanes === NoLanes) { + // This should only be reachable if we're suspended + // TODO: Consider warning in this path if a fallback timer is not scheduled. + return NoLanes; + } // If we're already in the middle of a render, switching lanes will interrupt + // it and we'll lose our progress. We should only do this if the new lanes are + // higher priority. - case REACT_SUSPENSE_LIST_TYPE: - return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); + if ( + wipLanes !== NoLanes && + wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't + // bother waiting until the root is complete. + (wipLanes & suspendedLanes) === NoLanes + ) { + var nextLane = getHighestPriorityLane(nextLanes); + var wipLane = getHighestPriorityLane(wipLanes); + + if ( + // Tests whether the next lane is equal or lower priority than the wip + // one. This works because the bits decrease in priority as you go left. + nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The + // only difference between default updates and transition updates is that + // default updates do not support refresh transitions. + (nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) + ) { + // Keep working on the existing in-progress tree. Do not interrupt. + return wipLanes; + } } - if (typeof type === "object") { - switch (type.$$typeof) { - case REACT_FORWARD_REF_TYPE: - return describeFunctionComponentFrame(type.render, source, ownerFn); + if ((nextLanes & InputContinuousLane) !== NoLanes) { + // When updates are sync by default, we entangle continuous priority updates + // and default updates, so they render in the same batch. The only reason + // they use separate lanes is because continuous updates should interrupt + // transitions, but default updates should not. + nextLanes |= pendingLanes & DefaultLane; + } // Check for entangled lanes and add them to the batch. + // + // A lane is said to be entangled with another when it's not allowed to render + // in a batch that does not also include the other lane. Typically we do this + // when multiple updates have the same source, and we only want to respond to + // the most recent event from that source. + // + // Note that we apply entanglements *after* checking for partial work above. + // This means that if a lane is entangled during an interleaved event while + // it's already rendering, we won't interrupt it. This is intentional, since + // entanglement is usually "best effort": we'll try our best to render the + // lanes in the same batch, but it's not worth throwing out partially + // completed work in order to do it. + // TODO: Reconsider this. The counter-argument is that the partial work + // represents an intermediate state, which we don't want to show to the user. + // And by spending extra time finishing it, we're increasing the amount of + // time it takes to show the final state, which is what they are actually + // waiting for. + // + // For those exceptions where entanglement is semantically important, like + // useMutableSource, we should ensure that there is no partial work at the + // time we apply the entanglement. - case REACT_MEMO_TYPE: - // Memo may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + var entangledLanes = root.entangledLanes; - case REACT_LAZY_TYPE: { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + if (entangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = nextLanes & entangledLanes; - try { - // Lazy may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV( - init(payload), - source, - ownerFn - ); - } catch (x) {} - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + nextLanes |= entanglements[index]; + lanes &= ~lane; } } - return ""; + return nextLanes; } +function getMostRecentEventTime(root, lanes) { + var eventTimes = root.eventTimes; + var mostRecentEventTime = NoTimestamp; -var loggedTypeFailures = {}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var eventTime = eventTimes[index]; -function setCurrentlyValidatingElement(element) { - { - if (element) { - var owner = element._owner; - var stack = describeUnknownElementTypeFrameInDEV( - element.type, - element._source, - owner ? owner.type : null - ); - ReactDebugCurrentFrame.setExtraStackFrame(stack); - } else { - ReactDebugCurrentFrame.setExtraStackFrame(null); + if (eventTime > mostRecentEventTime) { + mostRecentEventTime = eventTime; } - } -} - -function checkPropTypes(typeSpecs, values, location, componentName, element) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); - - for (var typeSpecName in typeSpecs) { - if (has(typeSpecs, typeSpecName)) { - var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - if (typeof typeSpecs[typeSpecName] !== "function") { - var err = Error( - (componentName || "React class") + - ": " + - location + - " type `" + - typeSpecName + - "` is invalid; " + - "it must be a function, usually from the `prop-types` package, but received `" + - typeof typeSpecs[typeSpecName] + - "`." + - "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." - ); - err.name = "Invariant Violation"; - throw err; - } - - error$1 = typeSpecs[typeSpecName]( - values, - typeSpecName, - componentName, - location, - null, - "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" - ); - } catch (ex) { - error$1 = ex; - } - - if (error$1 && !(error$1 instanceof Error)) { - setCurrentlyValidatingElement(element); - - error( - "%s: type specification of %s" + - " `%s` is invalid; the type checker " + - "function must return `null` or an `Error` but returned a %s. " + - "You may have forgotten to pass an argument to the type checker " + - "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + - "shape all require an argument).", - componentName || "React class", - location, - typeSpecName, - typeof error$1 - ); - setCurrentlyValidatingElement(null); - } + lanes &= ~lane; + } - if ( - error$1 instanceof Error && - !(error$1.message in loggedTypeFailures) - ) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error$1.message] = true; - setCurrentlyValidatingElement(element); + return mostRecentEventTime; +} - error("Failed %s type: %s", location, error$1.message); +function computeExpirationTime(lane, currentTime) { + switch (lane) { + case SyncLane: + case InputContinuousHydrationLane: + case InputContinuousLane: + // User interactions should expire slightly more quickly. + // + // NOTE: This is set to the corresponding constant as in Scheduler.js. + // When we made it larger, a product metric in www regressed, suggesting + // there's a user interaction that's being starved by a series of + // synchronous updates. If that theory is correct, the proper solution is + // to fix the starvation. However, this scenario supports the idea that + // expiration times are an important safeguard when starvation + // does happen. + return currentTime + 250; + + case DefaultHydrationLane: + case DefaultLane: + case TransitionHydrationLane: + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + case TransitionLane15: + case TransitionLane16: + return currentTime + 5000; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + case RetryLane5: + // TODO: Retries should be allowed to expire if they are CPU bound for + // too long, but when I made this change it caused a spike in browser + // crashes. There must be some other underlying bug; not super urgent but + // ideally should figure out why and fix it. Unfortunately we don't have + // a repro for the crashes, only detected via production metrics. + return NoTimestamp; + + case SelectiveHydrationLane: + case IdleHydrationLane: + case IdleLane: + case OffscreenLane: + // Anything idle priority or lower should never expire. + return NoTimestamp; - setCurrentlyValidatingElement(null); - } + default: + { + error("Should have found matching lanes. This is a bug in React."); } - } + + return NoTimestamp; } } -var valueStack = []; -var fiberStack; - -{ - fiberStack = []; -} +function markStarvedLanesAsExpired(root, currentTime) { + // TODO: This gets called every time we yield. We can optimize by storing + // the earliest expiration time on the root. Then use that to quickly bail out + // of this function. + var pendingLanes = root.pendingLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; + var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their + // expiration time. If so, we'll assume the update is being starved and mark + // it as expired to force it to finish. -var index = -1; + var lanes = pendingLanes; -function createCursor(defaultValue) { - return { - current: defaultValue - }; -} + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; -function pop(cursor, fiber) { - if (index < 0) { - { - error("Unexpected pop."); + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); + } + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; } - return; + lanes &= ~lane; } +} // This returns the highest priority pending lanes regardless of whether they +function getLanesToRetrySynchronouslyOnError(root) { + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - { - if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); - } + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; } - cursor.current = valueStack[index]; - valueStack[index] = null; - - { - fiberStack[index] = null; + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } - index--; + return NoLanes; +} +function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; +} +function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; +} +function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; } +function shouldTimeSlice(root, lanes) { + if ((lanes & root.expiredLanes) !== NoLanes) { + // At least one of these lanes expired. To prevent additional starvation, + // finish rendering without yielding execution. + return false; + } -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; + var SyncDefaultLanes = + InputContinuousHydrationLane | + InputContinuousLane | + DefaultHydrationLane | + DefaultLane; + return (lanes & SyncDefaultLanes) === NoLanes; +} +function isTransitionLane(lane) { + return (lane & TransitionLanes) !== 0; +} +function claimNextTransitionLane() { + // Cycle through the lanes, assigning each new transition to the next lane. + // In most cases, this means every transition gets its own lane, until we + // run out of lanes and cycle back to the beginning. + var lane = nextTransitionLane; + nextTransitionLane <<= 1; - { - fiberStack[index] = fiber; + if ((nextTransitionLane & TransitionLanes) === 0) { + nextTransitionLane = TransitionLane1; } - cursor.current = value; + return lane; } +function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; -var warnedAboutMissingGetChildContext; + if ((nextRetryLane & RetryLanes) === 0) { + nextRetryLane = RetryLane1; + } -{ - warnedAboutMissingGetChildContext = {}; + return lane; +} +function getHighestPriorityLane(lanes) { + return lanes & -lanes; +} +function pickArbitraryLane(lanes) { + // This wrapper function gets inlined. Only exists so to communicate that it + // doesn't matter which bit is selected; you can pick any bit without + // affecting the algorithms where its used. Here I'm using + // getHighestPriorityLane because it requires the fewest operations. + return getHighestPriorityLane(lanes); } -var emptyContextObject = {}; +function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); +} -{ - Object.freeze(emptyContextObject); -} // A cursor to the current merged context object on the stack. - -var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. - -var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. -// We use this to get access to the parent context after we have already -// pushed the next context provider, and now need to merge their contexts. +function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); +} -var previousContext = emptyContextObject; +function includesSomeLane(a, b) { + return (a & b) !== NoLanes; +} +function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; +} +function mergeLanes(a, b) { + return a | b; +} +function removeLanes(set, subset) { + return set & ~subset; +} +function intersectLanes(a, b) { + return a & b; +} // Seems redundant, but it changes the type from a single lane (used for +// updates) to a group of lanes (used for flushing work). -function getUnmaskedContext( - workInProgress, - Component, - didPushOwnContextIfProvider -) { - { - if (didPushOwnContextIfProvider && isContextProvider(Component)) { - // If the fiber is a context provider itself, when we read its context - // we may have already pushed its own child context on the stack. A context - // provider should not "see" its own child context. Therefore we read the - // previous (parent) context instead for a context provider. - return previousContext; - } +function laneToLanes(lane) { + return lane; +} +function createLaneMap(initial) { + // Intentionally pushing one by one. + // https://v8.dev/blog/elements-kinds#avoid-creating-holes + var laneMap = []; - return contextStackCursor.current; + for (var i = 0; i < TotalLanes; i++) { + laneMap.push(initial); } + + return laneMap; } +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update + // could unblock them. Clear the suspended lanes so that we can try rendering + // them again. + // + // TODO: We really only need to unsuspend only lanes that are in the + // `subtreeLanes` of the updated fiber, or the update lanes of the return + // path. This would exclude suspended updates in an unrelated sibling tree, + // since there's no way for this update to unblock it. + // + // We don't do this if the incoming update is idle, because we never process + // idle updates until after all the regular updates have finished; there's no + // way it could unblock a transition. -function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { - var instance = workInProgress.stateNode; - instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; - instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + if (updateLane !== IdleLane) { + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; } + + var eventTimes = root.eventTimes; + var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most + // recent event, and we assume time is monotonically increasing. + + eventTimes[index] = eventTime; } +function markRootSuspended(root, suspendedLanes) { + root.suspendedLanes |= suspendedLanes; + root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. -function getMaskedContext(workInProgress, unmaskedContext) { - { - var type = workInProgress.type; - var contextTypes = type.contextTypes; + var expirationTimes = root.expirationTimes; + var lanes = suspendedLanes; - if (!contextTypes) { - return emptyContextObject; - } // Avoid recreating masked context unless unmasked context has changed. - // Failing to do this will result in unnecessary calls to componentWillReceiveProps. - // This may trigger infinite loops if componentWillReceiveProps calls setState. + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; + } +} +function markRootPinged(root, pingedLanes, eventTime) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; +} +function markRootMutableRead(root, updateLane) { + root.mutableReadLanes |= updateLane & root.pendingLanes; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again - var instance = workInProgress.stateNode; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; - if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext - ) { - return instance.__reactInternalMemoizedMaskedChildContext; - } + var entanglements = root.entanglements; + var eventTimes = root.eventTimes; + var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work - var context = {}; + var lanes = noLongerPendingLanes; - for (var key in contextTypes) { - context[key] = unmaskedContext[key]; - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + eventTimes[index] = NoTimestamp; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + // In addition to entangling each of the given lanes with each other, we also + // have to consider _transitive_ entanglements. For each lane that is already + // entangled with *any* of the given lanes, that lane is now transitively + // entangled with *all* the given lanes. + // + // Translated: If C is entangled with A, then entangling A with B also + // entangles C with B. + // + // If this is hard to grasp, it might help to intentionally break this + // function and look at the tests that fail in ReactTransition-test.js. Try + // commenting out one of the conditions below. + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + var entanglements = root.entanglements; + var lanes = rootEntangledLanes; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); - } // Cache unmasked context so we can avoid recreating masked context unless necessary. - // Context is created before the class component is instantiated so check for instance. + while (lanes) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; - if (instance) { - cacheContext(workInProgress, unmaskedContext, context); + if ( + // Is this one of the newly entangled lanes? + (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? + (entanglements[index] & entangledLanes) + ) { + entanglements[index] |= entangledLanes; } - return context; + lanes &= ~lane; } } +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. +// Based on: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -function hasContextChanged() { - { - return didPerformWorkStackCursor.current; - } -} +var log = Math.log; +var LN2 = Math.LN2; -function isContextProvider(type) { - { - var childContextTypes = type.childContextTypes; - return childContextTypes !== null && childContextTypes !== undefined; +function clz32Fallback(lanes) { + if (lanes === 0) { + return 32; } + + return (31 - ((log(lanes) / LN2) | 0)) | 0; } -function popContext(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); - } +var DiscreteEventPriority = SyncLane; +var ContinuousEventPriority = InputContinuousLane; +var DefaultEventPriority = DefaultLane; +var IdleEventPriority = IdleLane; +var currentUpdatePriority = NoLane; +function getCurrentUpdatePriority() { + return currentUpdatePriority; +} +function setCurrentUpdatePriority(newPriority) { + currentUpdatePriority = newPriority; } +function higherEventPriority(a, b) { + return a !== 0 && a < b ? a : b; +} +function lowerEventPriority(a, b) { + return a === 0 || a > b ? a : b; +} +function isHigherEventPriority(a, b) { + return a !== 0 && a < b; +} +function lanesToEventPriority(lanes) { + var lane = getHighestPriorityLane(lanes); -function popTopLevelContextObject(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); + if (!isHigherEventPriority(DiscreteEventPriority, lane)) { + return DiscreteEventPriority; } -} -function pushTopLevelContextObject(fiber, context, didChange) { - { - if (!(contextStackCursor.current === emptyContextObject)) { - throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." - ); - } + if (!isHigherEventPriority(ContinuousEventPriority, lane)) { + return ContinuousEventPriority; + } - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + if (includesNonIdleWork(lane)) { + return DefaultEventPriority; } + + return IdleEventPriority; } -function processChildContext(fiber, type, parentContext) { +// can re-export everything from this module. + +function shim() { { - var instance = fiber.stateNode; - var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. - // It has only been added in Fiber to match the (unintentional) behavior in Stack. + throw Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ); + } +} // Hydration (when unsupported) +var isSuspenseInstancePending = shim; +var isSuspenseInstanceFallback = shim; +var hydrateTextInstance = shim; +var errorHydratingContainer = shim; - if (typeof instance.getChildContext !== "function") { - { - var componentName = getComponentName(type) || "Unknown"; +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; +var UPDATE_SIGNAL = {}; - if (!warnedAboutMissingGetChildContext[componentName]) { - warnedAboutMissingGetChildContext[componentName] = true; +{ + Object.freeze(UPDATE_SIGNAL); +} // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. - error( - "%s.childContextTypes is specified but there is no getChildContext() method " + - "on the instance. You can either define getChildContext() on %s or remove " + - "childContextTypes from it.", - componentName, - componentName - ); - } - } +var nextReactTag = 3; - return parentContext; - } +function allocateTag() { + var tag = nextReactTag; - var childContext = instance.getChildContext(); + if (tag % 10 === 1) { + tag += 2; + } - for (var contextKey in childContext) { - if (!(contextKey in childContextTypes)) { - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' - ); - } - } + nextReactTag = tag + 2; + return tag; +} - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); - } +function recursivelyUncacheFiberNode(node) { + if (typeof node === "number") { + // Leaf node (eg text) + uncacheFiberNode(node); + } else { + uncacheFiberNode(node._nativeTag); - return Object.assign({}, parentContext, childContext); + node._children.forEach(recursivelyUncacheFiberNode); } } - -function pushContextProvider(workInProgress) { - { - var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. - // If the instance does not exist yet, we will push null at first, - // and replace it on the stack later when invalidating the context. - - var memoizedMergedChildContext = - (instance && instance.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; // Remember the parent context so we can merge with it later. - // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. - - previousContext = contextStackCursor.current; - push(contextStackCursor, memoizedMergedChildContext, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); - return true; - } -} - -function invalidateContextProvider(workInProgress, type, didChange) { - { - var instance = workInProgress.stateNode; - - if (!instance) { - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); - } - - if (didChange) { - // Merge parent and own context. - // Skip this if we're not updating due to sCU. - // This avoids unnecessarily recomputing memoized values. - var mergedContext = processChildContext( - workInProgress, - type, - previousContext - ); - instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. - // It is important to unwind the context in the reverse order. - - pop(didPerformWorkStackCursor, workInProgress); - pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. - - push(contextStackCursor, mergedContext, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } else { - pop(didPerformWorkStackCursor, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } - } +function appendInitialChild(parentInstance, child) { + parentInstance._children.push(child); } +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + var tag = allocateTag(); + var viewConfig = getViewConfigForType(type); -function findCurrentUnmaskedContext(fiber) { { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw Error( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." - ); - } - - var node = fiber; - - do { - switch (node.tag) { - case HostRoot: - return node.stateNode.context; - - case ClassComponent: { - var Component = node.type; - - if (isContextProvider(Component)) { - return node.stateNode.__reactInternalMemoizedMergedChildContext; - } - - break; - } + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] + ); } - - node = node.return; - } while (node !== null); - - { - throw Error( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); } } -} - -var LegacyRoot = 0; -var BlockingRoot = 1; -var ConcurrentRoot = 2; - -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; - } - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var updatePayload = create(props, viewConfig.validAttributes); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload // props + ); + var component = new ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandle + ); + precacheFiberNode(internalInstanceHandle, tag); + updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined + // in the same file but if it's external it can't see the types. - if (hook.isDisabled) { - // This isn't a real property on the hook, but it can be set to opt out - // of DevTools integration and associated warnings and logs. - // https://github.com/facebook/react/issues/3877 - return true; + return component; +} +function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + if (!hostContext.isInAParentText) { + throw Error("Text strings must be rendered within a component."); } - if (!hook.supportsFiber) { + var tag = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. - - return true; - } - - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + text: text + } // props + ); + precacheFiberNode(internalInstanceHandle, tag); + return tag; +} +function finalizeInitialChildren( + parentInstance, + type, + props, + rootContainerInstance, + hostContext +) { + // Don't send a no-op message over the bridge. + if (parentInstance._children.length === 0) { + return false; + } // Map from child objects to native tags. + // Either way we need to pass a copy of the Array to prevent it from being frozen. - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists + var nativeTags = parentInstance._children.map(function(child) { + return typeof child === "number" + ? child // Leaf node (eg text) + : child._nativeTag; + }); - return true; + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance._nativeTag, // containerTag + nativeTags // reactTags + ); + return false; } -function onScheduleRoot(root, children) { - { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } +function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; } -function onCommitRoot(root, priorityLevel) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; - - if (enableProfilerTimer) { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; +function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; - error("React instrumentation encountered an error: %s", err); - } - } - } + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText + }; + } else { + return parentHostContext; } } -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } - } +function getPublicInstance(instance) { + return instance; } +function prepareForCommit(containerInfo) { + // Noop + return null; +} +function prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + hostContext +) { + return UPDATE_SIGNAL; +} +function resetAfterCommit(containerInfo) { + // Noop +} +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; +function shouldSetTextContent(type, props) { + // TODO (bvaughn) Revisit this decision. + // Always returning false simplifies the createInstance() implementation, + // But creates an additional child Fiber for raw text children. + // No additional native views are created though. + // It's not clear to me which is better so I'm deferring for now. + // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 + return false; +} +function getCurrentEventPriority() { + return DefaultEventPriority; +} // ------------------- +function appendChild(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + var children = parentInstance._children; + var index = children.indexOf(child); -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_now = Scheduler.unstable_now; - -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + if (index >= 0) { + children.splice(index, 1); + children.push(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerTag + [index], // moveFromIndices + [children.length - 1], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); + } else { + children.push(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerTag + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [children.length - 1], // addAtIndices + [] // removeAtIndices ); } } -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. - -var ImmediatePriority = 99; -var UserBlockingPriority = 98; -var NormalPriority = 97; -var LowPriority = 96; -var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - -var NoPriority = 90; -var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. - -var SyncLanePriority = 15; -var SyncBatchedLanePriority = 14; -var InputDiscreteHydrationLanePriority = 13; -var InputDiscreteLanePriority = 12; -var InputContinuousHydrationLanePriority = 11; -var InputContinuousLanePriority = 10; -var DefaultHydrationLanePriority = 9; -var DefaultLanePriority = 8; -var TransitionHydrationPriority = 7; -var TransitionPriority = 6; -var RetryLanePriority = 5; -var SelectiveHydrationLanePriority = 4; -var IdleHydrationLanePriority = 3; -var IdleLanePriority = 2; -var OffscreenLanePriority = 1; -var NoLanePriority = 0; -var TotalLanes = 31; -var NoLanes = - /* */ - 0; -var NoLane = - /* */ - 0; -var SyncLane = - /* */ - 1; -var SyncBatchedLane = - /* */ - 2; -var InputDiscreteHydrationLane = - /* */ - 4; -var InputDiscreteLanes = - /* */ - 24; -var InputContinuousHydrationLane = - /* */ - 32; -var InputContinuousLanes = - /* */ - 192; -var DefaultHydrationLane = - /* */ - 256; -var DefaultLanes = - /* */ - 3584; -var TransitionHydrationLane = - /* */ - 4096; -var TransitionLanes = - /* */ - 4186112; -var RetryLanes = - /* */ - 62914560; -var SomeRetryLane = - /* */ - 33554432; -var SelectiveHydrationLane = - /* */ - 67108864; -var NonIdleLanes = - /* */ - 134217727; -var IdleHydrationLane = - /* */ - 134217728; -var IdleLanes = - /* */ - 805306368; -var OffscreenLane = - /* */ - 1073741824; -var NoTimestamp = -1; -// Used by getHighestPriorityLanes and getNextLanes: - -var return_highestLanePriority = DefaultLanePriority; - -function getHighestPriorityLanes(lanes) { - if ((SyncLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncLanePriority; - return SyncLane; - } - - if ((SyncBatchedLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncBatchedLanePriority; - return SyncBatchedLane; - } - - if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { - return_highestLanePriority = InputDiscreteHydrationLanePriority; - return InputDiscreteHydrationLane; - } - - var inputDiscreteLanes = InputDiscreteLanes & lanes; - - if (inputDiscreteLanes !== NoLanes) { - return_highestLanePriority = InputDiscreteLanePriority; - return inputDiscreteLanes; - } - - if ((lanes & InputContinuousHydrationLane) !== NoLanes) { - return_highestLanePriority = InputContinuousHydrationLanePriority; - return InputContinuousHydrationLane; - } - - var inputContinuousLanes = InputContinuousLanes & lanes; - - if (inputContinuousLanes !== NoLanes) { - return_highestLanePriority = InputContinuousLanePriority; - return inputContinuousLanes; - } - - if ((lanes & DefaultHydrationLane) !== NoLanes) { - return_highestLanePriority = DefaultHydrationLanePriority; - return DefaultHydrationLane; - } - - var defaultLanes = DefaultLanes & lanes; - - if (defaultLanes !== NoLanes) { - return_highestLanePriority = DefaultLanePriority; - return defaultLanes; - } - - if ((lanes & TransitionHydrationLane) !== NoLanes) { - return_highestLanePriority = TransitionHydrationPriority; - return TransitionHydrationLane; - } - - var transitionLanes = TransitionLanes & lanes; - - if (transitionLanes !== NoLanes) { - return_highestLanePriority = TransitionPriority; - return transitionLanes; - } - - var retryLanes = RetryLanes & lanes; - - if (retryLanes !== NoLanes) { - return_highestLanePriority = RetryLanePriority; - return retryLanes; - } - - if (lanes & SelectiveHydrationLane) { - return_highestLanePriority = SelectiveHydrationLanePriority; - return SelectiveHydrationLane; - } - - if ((lanes & IdleHydrationLane) !== NoLanes) { - return_highestLanePriority = IdleHydrationLanePriority; - return IdleHydrationLane; - } - - var idleLanes = IdleLanes & lanes; - - if (idleLanes !== NoLanes) { - return_highestLanePriority = IdleLanePriority; - return idleLanes; - } - - if ((OffscreenLane & lanes) !== NoLanes) { - return_highestLanePriority = OffscreenLanePriority; - return OffscreenLane; - } - - { - error("Should have found matching lanes. This is a bug in React."); - } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - - return_highestLanePriority = DefaultLanePriority; - return lanes; +function appendChildToContainer(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance, // containerTag + [childTag] // reactTags + ); } - -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case ImmediatePriority: - return SyncLanePriority; - - case UserBlockingPriority: - return InputContinuousLanePriority; - - case NormalPriority: - case LowPriority: - // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. - return DefaultLanePriority; - - case IdlePriority: - return IdleLanePriority; - - default: - return NoLanePriority; - } +function commitTextUpdate(textInstance, oldText, newText) { + ReactNativePrivateInterface.UIManager.updateView( + textInstance, // reactTag + "RCTRawText", // viewName + { + text: newText + } // props + ); } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case SyncLanePriority: - case SyncBatchedLanePriority: - return ImmediatePriority; - - case InputDiscreteHydrationLanePriority: - case InputDiscreteLanePriority: - case InputContinuousHydrationLanePriority: - case InputContinuousLanePriority: - return UserBlockingPriority; - - case DefaultHydrationLanePriority: - case DefaultLanePriority: - case TransitionHydrationPriority: - case TransitionPriority: - case SelectiveHydrationLanePriority: - case RetryLanePriority: - return NormalPriority; - - case IdleHydrationLanePriority: - case IdleLanePriority: - case OffscreenLanePriority: - return IdlePriority; - - case NoLanePriority: - return NoPriority; +function commitUpdate( + instance, + updatePayloadTODO, + type, + oldProps, + newProps, + internalInstanceHandle +) { + var viewConfig = instance.viewConfig; + updateFiberProps(instance._nativeTag, newProps); + var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. + // This is an expensive no-op for Android, and causes an unnecessary + // view invalidation for certain components (eg RCTTextInput) on iOS. - default: { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } + if (updatePayload != null) { + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, // reactTag + viewConfig.uiViewClassName, // viewName + updatePayload // props + ); } } -function getNextLanes(root, wipLanes) { - // Early bailout if there's no pending work left. - var pendingLanes = root.pendingLanes; - - if (pendingLanes === NoLanes) { - return_highestLanePriority = NoLanePriority; - return NoLanes; - } - - var nextLanes = NoLanes; - var nextLanePriority = NoLanePriority; - var expiredLanes = root.expiredLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; // Check if any work has expired. +function insertBefore(parentInstance, child, beforeChild) { + var children = parentInstance._children; + var index = children.indexOf(child); // Move existing child or add new child? - if (expiredLanes !== NoLanes) { - nextLanes = expiredLanes; - nextLanePriority = return_highestLanePriority = SyncLanePriority; + if (index >= 0) { + children.splice(index, 1); + var beforeChildIndex = children.indexOf(beforeChild); + children.splice(beforeChildIndex, 0, child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [index], // moveFromIndices + [beforeChildIndex], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); } else { - // Do not work on any idle work until all the non-idle work has finished, - // even if the work is suspended. - var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - - if (nonIdlePendingLanes !== NoLanes) { - var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; - - if (nonIdleUnblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; - - if (nonIdlePingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } else { - // The only remaining work is Idle. - var unblockedLanes = pendingLanes & ~suspendedLanes; + var _beforeChildIndex = children.indexOf(beforeChild); - if (unblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(unblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - if (pingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(pingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } + children.splice(_beforeChildIndex, 0, child); + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [_beforeChildIndex], // addAtIndices + [] // removeAtIndices + ); } +} +function insertInContainerBefore(parentInstance, child, beforeChild) { + // TODO (bvaughn): Remove this check when... + // We create a wrapper object for the container in ReactNative render() + // Or we refactor to remove wrapper objects entirely. + // For more info on pros/cons see PR #8560 description. + if (!(typeof parentInstance !== "number")) { + throw Error("Container does not support insertBefore operation"); + } +} +function removeChild(parentInstance, child) { + recursivelyUncacheFiberNode(child); + var children = parentInstance._children; + var index = children.indexOf(child); + children.splice(index, 1); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [index] // removeAtIndices + ); +} +function removeChildFromContainer(parentInstance, child) { + recursivelyUncacheFiberNode(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [0] // removeAtIndices + ); +} +function resetTextContent(instance) { + // Noop +} +function hideInstance(instance) { + var viewConfig = instance.viewConfig; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); +} +function hideTextInstance(textInstance) { + throw new Error("Not yet implemented."); +} +function unhideInstance(instance, props) { + var viewConfig = instance.viewConfig; + var updatePayload = diff( + Object.assign({}, props, { + style: [ + props.style, + { + display: "none" + } + ] + }), + props, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); +} +function clearContainer(container) { + // TODO Implement this for React Native + // UIManager does not expose a "remove all" type method. +} +function unhideTextInstance(textInstance, text) { + throw new Error("Not yet implemented."); +} +function makeClientIdInDEV(warnOnAccessInDEV) { + throw new Error("Not yet implemented"); +} +function preparePortalMount(portalInstance) { + // noop +} - if (nextLanes === NoLanes) { - // This should only be reachable if we're suspended - // TODO: Consider warning in this path if a fallback timer is not scheduled. - return NoLanes; - } // If there are higher priority lanes, we'll include them even if they - // are suspended. - - nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt - // it and we'll lose our progress. We should only do this if the new lanes are - // higher priority. - - if ( - wipLanes !== NoLanes && - wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't - // bother waiting until the root is complete. - (wipLanes & suspendedLanes) === NoLanes - ) { - getHighestPriorityLanes(wipLanes); - var wipLanePriority = return_highestLanePriority; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +function describeBuiltInComponentFrame(name, source, ownerFn) { + { + var ownerName = null; - if (nextLanePriority <= wipLanePriority) { - return wipLanes; - } else { - return_highestLanePriority = nextLanePriority; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; } - } // Check for entangled lanes and add them to the batch. - // - // A lane is said to be entangled with another when it's not allowed to render - // in a batch that does not also include the other lane. Typically we do this - // when multiple updates have the same source, and we only want to respond to - // the most recent event from that source. - // - // Note that we apply entanglements *after* checking for partial work above. - // This means that if a lane is entangled during an interleaved event while - // it's already rendering, we won't interrupt it. This is intentional, since - // entanglement is usually "best effort": we'll try our best to render the - // lanes in the same batch, but it's not worth throwing out partially - // completed work in order to do it. - // - // For those exceptions where entanglement is semantically important, like - // useMutableSource, we should ensure that there is no partial work at the - // time we apply the entanglement. - - var entangledLanes = root.entangledLanes; - - if (entangledLanes !== NoLanes) { - var entanglements = root.entanglements; - var lanes = nextLanes & entangledLanes; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - nextLanes |= entanglements[index]; - lanes &= ~lane; - } + return describeComponentFrame(name, source, ownerName); } +} +var componentFrameCache; - return nextLanes; +{ + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); } -function getMostRecentEventTime(root, lanes) { - var eventTimes = root.eventTimes; - var mostRecentEventTime = NoTimestamp; +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var eventTime = eventTimes[index]; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; - if (eventTime > mostRecentEventTime) { - mostRecentEventTime = eventTime; + 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; + } + } } - lanes &= ~lane; + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } - return mostRecentEventTime; + return "\n in " + (name || "Unknown") + sourceInfo; } -function computeExpirationTime(lane, currentTime) { - // TODO: Expiration heuristic is constant per lane, so could use a map. - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; - - if (priority >= InputContinuousLanePriority) { - // User interactions should expire slightly more quickly. - // - // NOTE: This is set to the corresponding constant as in Scheduler.js. When - // we made it larger, a product metric in www regressed, suggesting there's - // a user interaction that's being starved by a series of synchronous - // updates. If that theory is correct, the proper solution is to fix the - // starvation. However, this scenario supports the idea that expiration - // times are an important safeguard when starvation does happen. - // - // Also note that, in the case of user input specifically, this will soon no - // longer be an issue because we plan to make user input synchronous by - // default (until you enter `startTransition`, of course.) - // - // If weren't planning to make these updates synchronous soon anyway, I - // would probably make this number a configurable parameter. - return currentTime + 250; - } else if (priority >= TransitionPriority) { - return currentTime + 5000; - } else { - // Anything idle priority or lower should never expire. - return NoTimestamp; +function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeFunctionComponentFrame(ctor, source, ownerFn); } } +function describeFunctionComponentFrame(fn, source, ownerFn) { + { + if (!fn) { + return ""; + } -function markStarvedLanesAsExpired(root, currentTime) { - // TODO: This gets called every time we yield. We can optimize by storing - // the earliest expiration time on the root. Then use that to quickly bail out - // of this function. - var pendingLanes = root.pendingLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; - var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their - // expiration time. If so, we'll assume the update is being starved and mark - // it as expired to force it to finish. + var name = fn.displayName || fn.name || null; + var ownerName = null; - var lanes = pendingLanes; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var expirationTime = expirationTimes[index]; + return describeComponentFrame(name, source, ownerName); + } +} - if (expirationTime === NoTimestamp) { - // Found a pending lane with no expiration time. If it's not suspended, or - // if it's pinged, assume it's CPU-bound. Compute a new expiration time - // using the current time. - if ( - (lane & suspendedLanes) === NoLanes || - (lane & pingedLanes) !== NoLanes - ) { - // Assumes timestamps are monotonically increasing. - expirationTimes[index] = computeExpirationTime(lane, currentTime); - } - } else if (expirationTime <= currentTime) { - // This lane expired - root.expiredLanes |= lane; - } +function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } - lanes &= ~lane; + if (typeof type === "function") { + { + return describeFunctionComponentFrame(type, source, ownerFn); + } } -} // This returns the highest priority pending lanes regardless of whether they -function getLanesToRetrySynchronouslyOnError(root) { - var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - if (everythingButOffscreen !== NoLanes) { - return everythingButOffscreen; + if (typeof type === "string") { + return describeBuiltInComponentFrame(type, source, ownerFn); } - if (everythingButOffscreen & OffscreenLane) { - return OffscreenLane; + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense", source, ownerFn); + + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); } - return NoLanes; -} -function returnNextLanesPriority() { - return return_highestLanePriority; -} -function includesNonIdleWork(lanes) { - return (lanes & NonIdleLanes) !== NoLanes; -} -function includesOnlyRetries(lanes) { - return (lanes & RetryLanes) === lanes; -} -function includesOnlyTransitions(lanes) { - return (lanes & TransitionLanes) === lanes; -} // To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render, source, ownerFn); -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case NoLanePriority: - break; + case REACT_MEMO_TYPE: + // Memo may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); - case SyncLanePriority: - return SyncLane; + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + + try { + // Lazy may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV( + init(payload), + source, + ownerFn + ); + } catch (x) {} + } + } + } - case SyncBatchedLanePriority: - return SyncBatchedLane; + return ""; +} - case InputDiscreteLanePriority: { - var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); +var hasOwnProperty = Object.prototype.hasOwnProperty; - if (_lane === NoLane) { - // Shift to the next priority level - return findUpdateLane(InputContinuousLanePriority, wipLanes); - } +var loggedTypeFailures = {}; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - return _lane; +function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV( + element.type, + element._source, + owner ? owner.type : null + ); + ReactDebugCurrentFrame.setExtraStackFrame(stack); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); } + } +} - case InputContinuousLanePriority: { - var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); +function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(hasOwnProperty); - if (_lane2 === NoLane) { - // Shift to the next priority level - return findUpdateLane(DefaultLanePriority, wipLanes); - } + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. - return _lane2; - } + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error( + (componentName || "React class") + + ": " + + location + + " type `" + + typeSpecName + + "` is invalid; " + + "it must be a function, usually from the `prop-types` package, but received `" + + typeof typeSpecs[typeSpecName] + + "`." + + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." + ); + err.name = "Invariant Violation"; + throw err; + } + + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } + + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); + + error( + "%s: type specification of %s" + + " `%s` is invalid; the type checker " + + "function must return `null` or an `Error` but returned a %s. " + + "You may have forgotten to pass an argument to the type checker " + + "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + + "shape all require an argument).", + componentName || "React class", + location, + typeSpecName, + typeof error$1 + ); + + setCurrentlyValidatingElement(null); + } - case DefaultLanePriority: { - var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); - if (_lane3 === NoLane) { - // If all the default lanes are already being worked on, look for a - // lane in the transition range. - _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); + error("Failed %s type: %s", location, error$1.message); - if (_lane3 === NoLane) { - // All the transition lanes are taken, too. This should be very - // rare, but as a last resort, pick a default lane. This will have - // the effect of interrupting the current work-in-progress render. - _lane3 = pickArbitraryLane(DefaultLanes); + setCurrentlyValidatingElement(null); } } - - return _lane3; } + } +} + +var valueStack = []; +var fiberStack; - case TransitionPriority: // Should be handled by findTransitionLane instead +{ + fiberStack = []; +} - case RetryLanePriority: - // Should be handled by findRetryLane instead - break; +var index = -1; - case IdleLanePriority: - var lane = pickArbitraryLane(IdleLanes & ~wipLanes); +function createCursor(defaultValue) { + return { + current: defaultValue + }; +} - if (lane === NoLane) { - lane = pickArbitraryLane(IdleLanes); - } +function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); + } - return lane; + return; } { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } } -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. -function findTransitionLane(wipLanes, pendingLanes) { - // First look for lanes that are completely unclaimed, i.e. have no - // pending work. - var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); - - if (lane === NoLane) { - // If all lanes have pending work, look for a lane that isn't currently - // being worked on. - lane = pickArbitraryLane(TransitionLanes & ~wipLanes); + cursor.current = valueStack[index]; + valueStack[index] = null; - if (lane === NoLane) { - // If everything is being worked on, pick any lane. This has the - // effect of interrupting the current work-in-progress. - lane = pickArbitraryLane(TransitionLanes); - } + { + fiberStack[index] = null; } - return lane; -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. + index--; +} -function findRetryLane(wipLanes) { - // This is a fork of `findUpdateLane` designed specifically for Suspense - // "retries" — a special update that attempts to flip a Suspense boundary - // from its placeholder state to its primary/resolved state. - var lane = pickArbitraryLane(RetryLanes & ~wipLanes); +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; - if (lane === NoLane) { - lane = pickArbitraryLane(RetryLanes); + { + fiberStack[index] = fiber; } - return lane; + cursor.current = value; } -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} +var warnedAboutMissingGetChildContext; -function getLowestPriorityLane(lanes) { - // This finds the most significant non-zero bit. - var index = 31 - clz32(lanes); - return index < 0 ? NoLanes : 1 << index; +{ + warnedAboutMissingGetChildContext = {}; } -function getEqualOrHigherPriorityLanes(lanes) { - return (getLowestPriorityLane(lanes) << 1) - 1; -} +var emptyContextObject = {}; -function pickArbitraryLane(lanes) { - // This wrapper function gets inlined. Only exists so to communicate that it - // doesn't matter which bit is selected; you can pick any bit without - // affecting the algorithms where its used. Here I'm using - // getHighestPriorityLane because it requires the fewest operations. - return getHighestPriorityLane(lanes); -} +{ + Object.freeze(emptyContextObject); +} // A cursor to the current merged context object on the stack. -function pickArbitraryLaneIndex(lanes) { - return 31 - clz32(lanes); -} +var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. -function laneToIndex(lane) { - return pickArbitraryLaneIndex(lane); -} +var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. +// We use this to get access to the parent context after we have already +// pushed the next context provider, and now need to merge their contexts. -function includesSomeLane(a, b) { - return (a & b) !== NoLanes; -} -function isSubsetOfLanes(set, subset) { - return (set & subset) === subset; -} -function mergeLanes(a, b) { - return a | b; -} -function removeLanes(set, subset) { - return set & ~subset; -} // Seems redundant, but it changes the type from a single lane (used for -// updates) to a group of lanes (used for flushing work). +var previousContext = emptyContextObject; -function laneToLanes(lane) { - return lane; -} -function createLaneMap(initial) { - // Intentionally pushing one by one. - // https://v8.dev/blog/elements-kinds#avoid-creating-holes - var laneMap = []; +function getUnmaskedContext( + workInProgress, + Component, + didPushOwnContextIfProvider +) { + { + if (didPushOwnContextIfProvider && isContextProvider(Component)) { + // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; + } - for (var i = 0; i < TotalLanes; i++) { - laneMap.push(initial); + return contextStackCursor.current; } - - return laneMap; } -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But - // it's not practical to try every single possible combination. We need a - // heuristic to decide which lanes to attempt to render, and in which batches. - // For now, we use the same heuristic as in the old ExpirationTimes model: - // retry any lane at equal or lower priority, but don't try updates at higher - // priority without also including the lower priority updates. This works well - // when considering updates across different priority levels, but isn't - // sufficient for updates within the same priority, since we want to treat - // those updates as parallel. - // Unsuspend any update at equal or lower priority. - - var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 - - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - var eventTimes = root.eventTimes; - var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most - // recent event, and we assume time is monotonically increasing. - eventTimes[index] = eventTime; +function cacheContext(workInProgress, unmaskedContext, maskedContext) { + { + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + } } -function markRootSuspended(root, suspendedLanes) { - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. - - var expirationTimes = root.expirationTimes; - var lanes = suspendedLanes; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } -} -function markRootPinged(root, pingedLanes, eventTime) { - root.pingedLanes |= root.suspendedLanes & pingedLanes; -} -function hasDiscreteLanes(lanes) { - return (lanes & InputDiscreteLanes) !== NoLanes; -} -function markRootMutableRead(root, updateLane) { - root.mutableReadLanes |= updateLane & root.pendingLanes; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; // Let's try everything again +function getMaskedContext(workInProgress, unmaskedContext) { + { + var type = workInProgress.type; + var contextTypes = type.contextTypes; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - var entanglements = root.entanglements; - var eventTimes = root.eventTimes; - var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work + if (!contextTypes) { + return emptyContextObject; + } // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. - var lanes = noLongerPendingLanes; + var instance = workInProgress.stateNode; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] = NoLanes; - eventTimes[index] = NoTimestamp; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; + if ( + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + ) { + return instance.__reactInternalMemoizedMaskedChildContext; + } + + var context = {}; + + for (var key in contextTypes) { + context[key] = unmaskedContext[key]; + } + + { + var name = getComponentNameFromFiber(workInProgress) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + // Context is created before the class component is instantiated so check for instance. + + if (instance) { + cacheContext(workInProgress, unmaskedContext, context); + } + + return context; } } -function markRootEntangled(root, entangledLanes) { - root.entangledLanes |= entangledLanes; - var entanglements = root.entanglements; - var lanes = entangledLanes; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] |= entangledLanes; - lanes &= ~lane; +function hasContextChanged() { + { + return didPerformWorkStackCursor.current; } } -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. -// Based on: -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -var log = Math.log; -var LN2 = Math.LN2; +function isContextProvider(type) { + { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; + } +} -function clz32Fallback(lanes) { - if (lanes === 0) { - return 32; +function popContext(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } +} - return (31 - ((log(lanes) / LN2) | 0)) | 0; +function popTopLevelContextObject(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } } -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +function pushTopLevelContextObject(fiber, context, didChange) { + { + if (!(contextStackCursor.current === emptyContextObject)) { + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); + } -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } } -var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. +function processChildContext(fiber, type, parentContext) { + { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. -var ImmediatePriority$1 = 99; -var UserBlockingPriority$1 = 98; -var NormalPriority$1 = 97; -var LowPriority$1 = 96; -var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. + if (typeof instance.getChildContext !== "function") { + { + var componentName = getComponentNameFromFiber(fiber) || "Unknown"; -var NoPriority$1 = 90; -var shouldYield = Scheduler_shouldYield; -var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. - Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; -var syncQueue = null; -var immediateQueueCallbackNode = null; -var isFlushingSyncQueue = false; -var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// This will be the case for modern browsers that support `performance.now`. In -// older browsers, Scheduler falls back to `Date.now`, which returns a Unix -// timestamp. In that case, subtract the module initialization time to simulate -// the behavior of performance.now and keep our times small enough to fit -// within 32 bits. -// TODO: Consider lifting this into Scheduler. - -var now = - initialTimeMs$1 < 10000 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return ImmediatePriority$1; + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; - case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; + error( + "%s.childContextTypes is specified but there is no getChildContext() method " + + "on the instance. You can either define getChildContext() on %s or remove " + + "childContextTypes from it.", + componentName, + componentName + ); + } + } - case Scheduler_NormalPriority: - return NormalPriority$1; + return parentContext; + } - case Scheduler_LowPriority: - return LowPriority$1; + var childContext = instance.getChildContext(); - case Scheduler_IdlePriority: - return IdlePriority$1; + for (var contextKey in childContext) { + if (!(contextKey in childContextTypes)) { + throw Error( + (getComponentNameFromFiber(fiber) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); + } + } - default: { - throw Error("Unknown priority level."); + { + var name = getComponentNameFromFiber(fiber) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); } + + return Object.assign({}, parentContext, childContext); } } -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case ImmediatePriority$1: - return Scheduler_ImmediatePriority; +function pushContextProvider(workInProgress) { + { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. + + var memoizedMergedChildContext = + (instance && instance.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. - case UserBlockingPriority$1: - return Scheduler_UserBlockingPriority; + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); + return true; + } +} - case NormalPriority$1: - return Scheduler_NormalPriority; +function invalidateContextProvider(workInProgress, type, didChange) { + { + var instance = workInProgress.stateNode; - case LowPriority$1: - return Scheduler_LowPriority; + if (!instance) { + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); + } - case IdlePriority$1: - return Scheduler_IdlePriority; + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext( + workInProgress, + type, + previousContext + ); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. - default: { - throw Error("Unknown priority level."); + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } } } -function runWithPriority(reactPriorityLevel, fn) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(priorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(priorityLevel, callback, options); +function findCurrentUnmaskedContext(fiber) { + { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ); + } + + var node = fiber; + + do { + switch (node.tag) { + case HostRoot: + return node.stateNode.context; + + case ClassComponent: { + var Component = node.type; + + if (isContextProvider(Component)) { + return node.stateNode.__reactInternalMemoizedMergedChildContext; + } + + break; + } + } + + node = node.return; + } while (node !== null); + + { + throw Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ); + } + } } + +var LegacyRoot = 0; +var ConcurrentRoot = 1; + +var syncQueue = null; +var includesLegacySyncCallbacks = false; +var isFlushingSyncQueue = false; 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 - ); + syncQueue = [callback]; } 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 scheduleLegacySyncCallback(callback) { + includesLegacySyncCallbacks = true; + scheduleSyncCallback(callback); } -function flushSyncCallbackQueue() { - if (immediateQueueCallbackNode !== null) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); +function flushSyncCallbacksOnlyInLegacyMode() { + // Only flushes the queue if there's a legacy sync callback scheduled. + // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So + // it might make more sense for the queue to be a list of roots instead of a + // list of generic callbacks. Then we can have two: one for legacy roots, one + // for concurrent roots. And this method would only flush the legacy ones. + if (includesLegacySyncCallbacks) { + flushSyncCallbacks(); } - - flushSyncCallbackQueueImpl(); } - -function flushSyncCallbackQueueImpl() { +function flushSyncCallbacks() { if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. isFlushingSyncQueue = true; var i = 0; + var previousUpdatePriority = getCurrentUpdatePriority(); - { - try { - var _isSync2 = true; - var _queue = syncQueue; - runWithPriority(ImmediatePriority$1, function() { - for (; i < _queue.length; i++) { - var callback = _queue[i]; - - do { - callback = callback(_isSync2); - } while (callback !== null); - } - }); - syncQueue = null; - } catch (error) { - // If something throws, leave the remaining callbacks on the queue. - if (syncQueue !== null) { - syncQueue = syncQueue.slice(i + 1); - } // Resume flushing in the next tick - - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ); - throw error; - } finally { - isFlushingSyncQueue = false; - } - } - } + try { + var isSync = true; + var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this + // queue is in the render or commit phases. + + setCurrentUpdatePriority(DiscreteEventPriority); + + for (; i < queue.length; i++) { + var callback = queue[i]; + + do { + callback = callback(isSync); + } while (callback !== null); + } + + syncQueue = null; + includesLegacySyncCallbacks = false; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); + } // Resume flushing in the next tick + + scheduleCallback(ImmediatePriority, flushSyncCallbacks); + throw error; + } finally { + setCurrentUpdatePriority(previousUpdatePriority); + isFlushingSyncQueue = false; + } + } + + return null; } -// TODO: this is special because it gets imported during build. -var ReactVersion = "17.0.1-454c2211c"; +var NoFlags$1 = + /* */ + 0; // Represents whether effect should fire. + +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. -var NoMode = 0; -var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root -// tag instead +var Layout = + /* */ + 2; +var Passive$1 = + /* */ + 4; -var BlockingMode = 2; -var ConcurrentMode = 4; -var ProfileMode = 8; -var DebugTracingMode = 16; +var ReactVersion = "17.0.3-experimental-2d8d133e1"; var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = 0; @@ -5950,7 +6005,6 @@ function is(x, y) { var objectIs = typeof Object.is === "function" ? Object.is : is; -var hasOwnProperty = Object.prototype.hasOwnProperty; /** * Performs equality by iterating through keys on an object and returning false * when any key has values which are not strictly equal between the arguments. @@ -6051,7 +6105,7 @@ function getCurrentFiberOwnerNameInDevOrNull() { var owner = current._debugOwner; if (owner !== null && typeof owner !== "undefined") { - return getComponentName(owner.type); + return getComponentNameFromFiber(owner); } } @@ -6108,7 +6162,7 @@ var ReactStrictModeWarnings = { var node = fiber; while (node !== null) { - if (node.mode & StrictMode) { + if (node.mode & StrictLegacyMode) { maybeStrictRoot = node; } @@ -6139,7 +6193,7 @@ var ReactStrictModeWarnings = { fiber, instance ) { - // Dedup strategy: Warn once per component. + // Dedupe strategy: Warn once per component. if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } @@ -6152,7 +6206,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function" ) { pendingUNSAFE_ComponentWillMountWarnings.push(fiber); @@ -6166,7 +6220,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); @@ -6180,7 +6234,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function" ) { pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); @@ -6194,7 +6248,7 @@ var ReactStrictModeWarnings = { if (pendingComponentWillMountWarnings.length > 0) { pendingComponentWillMountWarnings.forEach(function(fiber) { componentWillMountUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -6206,7 +6260,7 @@ var ReactStrictModeWarnings = { if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { UNSAFE_componentWillMountUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -6218,7 +6272,7 @@ var ReactStrictModeWarnings = { if (pendingComponentWillReceivePropsWarnings.length > 0) { pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { componentWillReceivePropsUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -6230,7 +6284,7 @@ var ReactStrictModeWarnings = { if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { UNSAFE_componentWillReceivePropsUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -6242,7 +6296,7 @@ var ReactStrictModeWarnings = { if (pendingComponentWillUpdateWarnings.length > 0) { pendingComponentWillUpdateWarnings.forEach(function(fiber) { componentWillUpdateUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -6254,7 +6308,7 @@ var ReactStrictModeWarnings = { if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { UNSAFE_componentWillUpdateUniqueNames.add( - getComponentName(fiber.type) || "Component" + getComponentNameFromFiber(fiber) || "Component" ); didWarnAboutUnsafeLifecycles.add(fiber.type); }); @@ -6409,7 +6463,7 @@ var ReactStrictModeWarnings = { var firstFiber = fiberArray[0]; var uniqueNames = new Set(); fiberArray.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); + uniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); didWarnAboutLegacyContext.add(fiber.type); }); var sortedNames = setToSortedString(uniqueNames); @@ -6460,11 +6514,6 @@ function resolveDefaultProps(Component, baseProps) { return baseProps; } -// Max 31 bit integer. The max integer size in V8 for 32-bit systems. -// Math.pow(2, 30) - 1 -// 0b111111111111111111111111111111 -var MAX_SIGNED_31_BIT_INT = 1073741823; - var valueCursor = createCursor(null); var rendererSigil; @@ -6475,14 +6524,14 @@ var rendererSigil; var currentlyRenderingFiber = null; var lastContextDependency = null; -var lastContextWithAllBitsObserved = null; +var lastFullyObservedContext = 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; + lastFullyObservedContext = null; { isDisallowedContextReadInDEV = false; @@ -6498,9 +6547,7 @@ function exitDisallowedContextReadInDEV() { isDisallowedContextReadInDEV = false; } } -function pushProvider(providerFiber, nextValue) { - var context = providerFiber.type._context; - +function pushProvider(providerFiber, context, nextValue) { { push(valueCursor, context._currentValue, providerFiber); context._currentValue = nextValue; @@ -6521,38 +6568,14 @@ function pushProvider(providerFiber, nextValue) { } } } -function popProvider(providerFiber) { +function popProvider(context, providerFiber) { var currentValue = valueCursor.current; pop(valueCursor, providerFiber); - var context = providerFiber.type._context; { context._currentValue = currentValue; } } -function calculateChangedBits(context, newValue, oldValue) { - if (objectIs(oldValue, newValue)) { - // No change - return 0; - } else { - var changedBits = - typeof context._calculateChangedBits === "function" - ? context._calculateChangedBits(oldValue, newValue) - : MAX_SIGNED_31_BIT_INT; - - { - if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { - error( - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); - } - } - - return changedBits | 0; - } -} function scheduleWorkOnParentPath(parent, renderLanes) { // Update the child lanes of all the ancestors, including the alternates. var node = parent; @@ -6580,12 +6603,13 @@ function scheduleWorkOnParentPath(parent, renderLanes) { node = node.return; } } -function propagateContextChange( - workInProgress, - context, - changedBits, - renderLanes -) { +function propagateContextChange(workInProgress, context, renderLanes) { + { + propagateContextChange_eager(workInProgress, context, renderLanes); + } +} + +function propagateContextChange_eager(workInProgress, context, renderLanes) { var fiber = workInProgress.child; if (fiber !== null) { @@ -6604,23 +6628,35 @@ function propagateContextChange( while (dependency !== null) { // Check if the context matches. - if ( - dependency.context === context && - (dependency.observedBits & changedBits) !== 0 - ) { + if (dependency.context === context) { // Match! Schedule an update on this fiber. if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate( - NoTimestamp, - pickArbitraryLane(renderLanes) - ); + var lane = pickArbitraryLane(renderLanes); + var update = createUpdate(NoTimestamp, lane); update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the // update to the current fiber, too, which means it will persist even if // this render is thrown away. Since it's a race condition, not sure it's // worth fixing. + // Inlined `enqueueUpdate` to remove interleaved update check + + var updateQueue = fiber.updateQueue; + + if (updateQueue === null); + else { + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - enqueueUpdate(fiber, update); + sharedQueue.pending = update; + } } fiber.lanes = mergeLanes(fiber.lanes, renderLanes); @@ -6681,23 +6717,25 @@ function propagateContextChange( function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; lastContextDependency = null; - lastContextWithAllBitsObserved = null; + lastFullyObservedContext = null; var dependencies = workInProgress.dependencies; if (dependencies !== null) { - var firstContext = dependencies.firstContext; + { + var firstContext = dependencies.firstContext; - if (firstContext !== null) { - if (includesSomeLane(dependencies.lanes, renderLanes)) { - // Context list has a pending update. Mark that this fiber performed work. - markWorkInProgressReceivedUpdate(); - } // Reset the work-in-progress list + if (firstContext !== null) { + if (includesSomeLane(dependencies.lanes, renderLanes)) { + // Context list has a pending update. Mark that this fiber performed work. + markWorkInProgressReceivedUpdate(); + } // Reset the work-in-progress list - dependencies.firstContext = null; + dependencies.firstContext = null; + } } } } -function readContext(context, observedBits) { +function readContext(context) { { // This warning would fire if you read context inside a Hook like useMemo. // Unlike the class check below, it's not enforced in production for perf. @@ -6711,25 +6749,13 @@ function readContext(context, observedBits) { } } - if (lastContextWithAllBitsObserved === context); - else if (observedBits === false || observedBits === 0); - else { - var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. - - if ( - typeof observedBits !== "number" || - observedBits === MAX_SIGNED_31_BIT_INT - ) { - // Observe all updates. - lastContextWithAllBitsObserved = context; - resolvedObservedBits = MAX_SIGNED_31_BIT_INT; - } else { - resolvedObservedBits = observedBits; - } + var value = context._currentValue; + if (lastFullyObservedContext === context); + else { var contextItem = { context: context, - observedBits: resolvedObservedBits, + memoizedValue: value, next: null }; @@ -6744,6 +6770,7 @@ function readContext(context, observedBits) { currentlyRenderingFiber.dependencies = { lanes: NoLanes, firstContext: contextItem, + // TODO: This is an old field. Delete it. responders: null }; } else { @@ -6752,7 +6779,49 @@ function readContext(context, observedBits) { } } - return context._currentValue; + return value; +} + +// An array of all update queues that received updates during the current +// render. When this render exits, either because it finishes or because it is +// interrupted, the interleaved updates will be transfered onto the main part +// of the queue. +var interleavedQueues = null; +function pushInterleavedQueue(queue) { + if (interleavedQueues === null) { + interleavedQueues = [queue]; + } else { + interleavedQueues.push(queue); + } +} +function enqueueInterleavedUpdates() { + // Transfer the interleaved updates onto the main queue. Each queue has a + // `pending` field and an `interleaved` field. When they are not null, they + // point to the last node in a circular linked list. We need to append the + // interleaved list to the end of the pending list by joining them into a + // single, circular list. + if (interleavedQueues !== null) { + for (var i = 0; i < interleavedQueues.length; i++) { + var queue = interleavedQueues[i]; + var lastInterleavedUpdate = queue.interleaved; + + if (lastInterleavedUpdate !== null) { + queue.interleaved = null; + var firstInterleavedUpdate = lastInterleavedUpdate.next; + var lastPendingUpdate = queue.pending; + + if (lastPendingUpdate !== null) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = firstInterleavedUpdate; + lastInterleavedUpdate.next = firstPendingUpdate; + } + + queue.pending = lastInterleavedUpdate; + } + } + + interleavedQueues = null; + } } var UpdateState = 0; @@ -6777,7 +6846,9 @@ function initializeUpdateQueue(fiber) { firstBaseUpdate: null, lastBaseUpdate: null, shared: { - pending: null + pending: null, + interleaved: null, + lanes: NoLanes }, effects: null }; @@ -6810,7 +6881,7 @@ function createUpdate(eventTime, lane) { }; return update; } -function enqueueUpdate(fiber, update) { +function enqueueUpdate(fiber, update, lane) { var updateQueue = fiber.updateQueue; if (updateQueue === null) { @@ -6819,17 +6890,35 @@ function enqueueUpdate(fiber, update) { } var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (isInterleavedUpdate(fiber)) { + var interleaved = sharedQueue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(sharedQueue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + sharedQueue.interleaved = update; } else { - update.next = pending.next; - pending.next = update; - } + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - sharedQueue.pending = update; + sharedQueue.pending = update; + } { if ( @@ -6847,6 +6936,33 @@ function enqueueUpdate(fiber, update) { } } } +function entangleTransitions(root, fiber, lane) { + var updateQueue = fiber.updateQueue; + + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; + } + + var sharedQueue = updateQueue.shared; + + if (isTransitionLane(lane)) { + var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must + // have finished. We can remove them from the shared queue, which represents + // a superset of the actually pending lanes. In some cases we may entangle + // more than we need to, but that's OK. In fact it's worse if we *don't* + // entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } +} function enqueueCapturedUpdate(workInProgress, capturedUpdate) { // Captured updates are updates that are thrown by a child during the render // phase. They should be discarded if the render is aborted. Therefore, @@ -7116,7 +7232,11 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { ); var callback = update.callback; - if (callback !== null) { + if ( + callback !== null && // If the update was already committed, we should not queue its + // callback again. + update.lane !== NoLane + ) { workInProgress.flags |= Callback; var effects = queue.effects; @@ -7156,7 +7276,24 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { queue.baseState = newBaseState; queue.firstBaseUpdate = newFirstBaseUpdate; - queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. + queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.shared.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + newLanes = mergeLanes(newLanes, interleaved.lane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (firstBaseUpdate === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.shared.lanes = NoLanes; + } // Set the remaining expiration time to be whatever is remaining in the queue. // This should be fine because the only two other things that contribute to // expiration time are props and context. We're already in the middle of the // begin phase by the time we start processing the queue, so we've already @@ -7209,8 +7346,7 @@ function commitUpdateQueue(finishedWork, finishedQueue, instance) { } } -var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7257,7 +7393,7 @@ var didWarnAboutInvalidateContextType; warnOnUndefinedDerivedState = function(type, partialState) { if (partialState === undefined) { - var componentName = getComponentName(type) || "Component"; + var componentName = getComponentNameFromType(type) || "Component"; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); @@ -7315,6 +7451,7 @@ function applyDerivedStateFromProps( updateQueue.baseState = memoizedState; } } + var classComponentUpdater = { isMounted: isMounted, enqueueSetState: function(inst, payload, callback) { @@ -7333,7 +7470,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); @@ -7352,7 +7493,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); @@ -7370,7 +7515,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } } }; @@ -7397,7 +7546,7 @@ function checkShouldComponentUpdate( error( "%s.shouldComponentUpdate(): Returned undefined instead of a " + "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" + getComponentNameFromType(ctor) || "Component" ); } } @@ -7418,7 +7567,7 @@ function checkClassInstance(workInProgress, ctor, newProps) { var instance = workInProgress.stateNode; { - var name = getComponentName(ctor) || "Component"; + var name = getComponentNameFromType(ctor) || "Component"; var renderPresent = instance.render; if (!renderPresent) { @@ -7521,7 +7670,7 @@ function checkClassInstance(workInProgress, ctor, newProps) { "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", - getComponentName(ctor) || "A pure component" + getComponentNameFromType(ctor) || "A pure component" ); } @@ -7591,7 +7740,7 @@ function checkClassInstance(workInProgress, ctor, newProps) { error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", - getComponentName(ctor) + getComponentNameFromType(ctor) ); } @@ -7690,7 +7839,7 @@ function constructClassInstance(workInProgress, ctor, props) { error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", - getComponentName(ctor) || "Component", + getComponentNameFromType(ctor) || "Component", addendum ); } @@ -7718,7 +7867,7 @@ function constructClassInstance(workInProgress, ctor, props) { { if (typeof ctor.getDerivedStateFromProps === "function" && state === null) { - var componentName = getComponentName(ctor) || "Component"; + var componentName = getComponentNameFromType(ctor) || "Component"; if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); @@ -7779,7 +7928,7 @@ function constructClassInstance(workInProgress, ctor, props) { foundWillReceivePropsName !== null || foundWillUpdateName !== null ) { - var _componentName = getComponentName(ctor) || "Component"; + var _componentName = getComponentNameFromType(ctor) || "Component"; var newApiName = typeof ctor.getDerivedStateFromProps === "function" @@ -7832,7 +7981,7 @@ function callComponentWillMount(workInProgress, instance) { "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", - getComponentName(workInProgress.type) || "Component" + getComponentNameFromFiber(workInProgress) || "Component" ); } @@ -7858,7 +8007,8 @@ function callComponentWillReceiveProps( if (instance.state !== oldState) { { - var componentName = getComponentName(workInProgress.type) || "Component"; + var componentName = + getComponentNameFromFiber(workInProgress) || "Component"; if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); @@ -7897,7 +8047,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { { if (instance.state === newProps) { - var componentName = getComponentName(ctor) || "Component"; + var componentName = getComponentNameFromType(ctor) || "Component"; if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); @@ -7911,7 +8061,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -7926,7 +8076,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; @@ -7955,7 +8104,9 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + var fiberFlags = Update; + + workInProgress.flags |= fiberFlags; } } @@ -8017,7 +8168,9 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + var fiberFlags = Update; + + workInProgress.flags |= fiberFlags; } return false; @@ -8063,13 +8216,17 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + var _fiberFlags = Update; + + workInProgress.flags |= _fiberFlags; } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + var _fiberFlags2 = Update; + + workInProgress.flags |= _fiberFlags2; } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8148,7 +8305,8 @@ function updateClassInstance( unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && - !checkHasForceUpdateAfterProcessing() + !checkHasForceUpdateAfterProcessing() && + !enableLazyContextPropagation ) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. @@ -8193,7 +8351,11 @@ function updateClassInstance( oldState, newState, nextContext - ); + ) || // TODO: In some cases, we'll end up checking if context has changed twice, + // both before and after `shouldComponentUpdate` has been called. Not ideal, + // but I'm loath to refactor this function. This only happens for memoized + // components so it's not that common. + enableLazyContextPropagation; if (shouldUpdate) { // In order to support react-lifecycles-compat polyfilled components, @@ -8289,7 +8451,7 @@ var warnForMissingKey = function(child, returnFiber) {}; } child._store.validated = true; - var componentName = getComponentName(returnFiber.type) || "Component"; + var componentName = getComponentNameFromFiber(returnFiber) || "Component"; if (ownerHasKeyUseWarning[componentName]) { return; @@ -8305,8 +8467,6 @@ var warnForMissingKey = function(child, returnFiber) {}; }; } -var isArray$1 = Array.isArray; - function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; @@ -8319,7 +8479,7 @@ function coerceRef(returnFiber, current, element) { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant if ( - (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + (returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs // because these cannot be automatically converted to an arrow function // using a codemod. Therefore, we don't have to warn about string refs again. !( @@ -8328,7 +8488,8 @@ function coerceRef(returnFiber, current, element) { element._owner.stateNode !== element._self ) ) { - var componentName = getComponentName(returnFiber.type) || "Component"; + var componentName = + getComponentNameFromFiber(returnFiber) || "Component"; if (!didWarnAboutStringRefs[componentName]) { { @@ -8420,22 +8581,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { - if (returnFiber.type !== "textarea") { - { - throw 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) + - "). If you meant to render a collection of children, use an array instead." - ); - } + var childString = Object.prototype.toString.call(newChild); + + { + throw Error( + "Objects are not valid as a React child (found: " + + (childString === "[object Object]" + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : childString) + + "). If you meant to render a collection of children, use an array instead." + ); } } function warnOnFunctionType(returnFiber) { { - var componentName = getComponentName(returnFiber.type) || "Component"; + var componentName = getComponentNameFromFiber(returnFiber) || "Component"; if (ownerHasFunctionTypeWarning[componentName]) { return; @@ -8449,7 +8610,7 @@ function warnOnFunctionType(returnFiber) { "Or maybe you meant to call this function rather than return it." ); } -} // This wrapper function exists because I expect to clone the code in each path +} // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. @@ -8459,23 +8620,16 @@ function ChildReconciler(shouldTrackSideEffects) { if (!shouldTrackSideEffects) { // Noop. return; - } // Deletions are added in reversed order so we add it to the front. - // At this point, the return fiber's effect list is empty except for - // deletions, so we can just append the deletion to the list. The remaining - // effects aren't added until the complete phase. Once we implement - // resuming, this may not be true. + } - var last = returnFiber.lastEffect; + var deletions = returnFiber.deletions; - if (last !== null) { - last.nextEffect = childToDelete; - returnFiber.lastEffect = childToDelete; + if (deletions === null) { + returnFiber.deletions = [childToDelete]; + returnFiber.flags |= ChildDeletion; } else { - returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + deletions.push(childToDelete); } - - childToDelete.nextEffect = null; - childToDelete.flags = Deletion; } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -8539,7 +8693,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (oldIndex < lastPlacedIndex) { // This is a move. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } else { // This item can stay in place. @@ -8547,7 +8701,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } else { // This is an insertion. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } } @@ -8556,7 +8710,7 @@ function ChildReconciler(shouldTrackSideEffects) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { - newFiber.flags = Placement; + newFiber.flags |= Placement; } return newFiber; @@ -8577,10 +8731,26 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current, element, lanes) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + } + if (current !== null) { if ( - current.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current, element) + current.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + enableLazyElements ) { // Move based on index var existing = useFiber(current, element.props); @@ -8676,7 +8846,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, @@ -8719,16 +8889,6 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ); - } - return updateElement(returnFiber, oldFiber, newChild, lanes); } else { return null; @@ -8744,7 +8904,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -8786,16 +8946,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key === null ? newIdx : newChild.key ) || null; - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - _matchedFiber, - newChild.props.children, - lanes, - newChild.key - ); - } - return updateElement(returnFiber, _matchedFiber, newChild, lanes); } @@ -8809,7 +8959,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateFragment( @@ -9289,45 +9439,43 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - switch (child.tag) { - case Fragment: { - if (element.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, element.props.children); - existing.return = returnFiber; + var elementType = element.type; - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; - return existing; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - break; + return existing; } + } else { + if ( + child.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + enableLazyElements + ) { + deleteRemainingChildren(returnFiber, child.sibling); - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing = useFiber(child, element.props); - - _existing.ref = coerceRef(returnFiber, child, element); - _existing.return = returnFiber; + var _existing = useFiber(child, element.props); - { - _existing._debugSource = element._source; - _existing._debugOwner = element._owner; - } + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; - return _existing; + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; } - break; + return _existing; } } // Didn't match. @@ -9421,9 +9569,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild = newChild.props.children; } // Handle object types - var isObject = typeof newChild === "object" && newChild !== null; - - if (isObject) { + if (typeof newChild === "object" && newChild !== null) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return placeSingleChild( @@ -9445,6 +9591,26 @@ function ChildReconciler(shouldTrackSideEffects) { ) ); } + + if (isArray(newChild)) { + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + } + + if (getIteratorFn(newChild)) { + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + } + + throwOnInvalidObjectType(returnFiber, newChild); } if (typeof newChild === "string" || typeof newChild === "number") { @@ -9458,28 +9624,6 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray$1(newChild)) { - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - } - - if (getIteratorFn(newChild)) { - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - } - - if (isObject) { - throwOnInvalidObjectType(returnFiber, newChild); - } - { if (typeof newChild === "function") { warnOnFunctionType(returnFiber); @@ -9510,7 +9654,7 @@ function ChildReconciler(shouldTrackSideEffects) { case SimpleMemoComponent: { { throw Error( - (getComponentName(returnFiber.type) || "Component") + + (getComponentNameFromFiber(returnFiber) || "Component") + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." ); } @@ -9758,21 +9902,6 @@ function findFirstSuspended(row) { return null; } -var NoFlags$1 = - /* */ - 0; // Represents whether effect should fire. - -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ - 2; -var Passive$1 = - /* */ - 4; - var isHydrating = false; function enterHydrationState(fiber) { @@ -9868,6 +9997,12 @@ function warnAboutMultipleRenderersDEV(mutableSource) { } } // Eager reads the version of a mutable source and stores it on the root. +function getSuspendedCachePool() { + { + return null; + } // We check the cache on the stack first, since that's the one any new Caches +} + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; @@ -9940,7 +10075,7 @@ function updateHookTypesDev() { function checkDepsAreArrayDev(deps) { { - if (deps !== undefined && deps !== null && !Array.isArray(deps)) { + if (deps !== undefined && deps !== null && !isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. error( @@ -9955,7 +10090,7 @@ function checkDepsAreArrayDev(deps) { function warnOnHookMismatchInDev(currentHookName) { { - var componentName = getComponentName(currentlyRenderingFiber$1.type); + var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1); if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { didWarnAboutMismatchedHooksForComponent.add(componentName); @@ -10153,7 +10288,25 @@ function renderWithHooks( { currentHookNameInDev = null; hookTypesDev = null; - hookTypesUpdateIndexDev = -1; + hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last + // render. If this fires, it suggests that we incorrectly reset the static + // flags in some other part of the codebase. This has happened before, for + // example, in the SuspenseList implementation. + + if ( + current !== null && + (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird + // and creates false positives. To make this work in legacy mode, we'd + // need to mark fibers that commit in an incomplete state, somehow. For + // now I'll disable the warning that most of the bugs that would trigger + // it are either exclusive to concurrent mode or exist in both. + (current.mode & ConcurrentMode) !== NoMode + ) { + error( + "Internal React error: Expected static flag was missing. Please " + + "notify the React team." + ); + } } didScheduleRenderPhaseUpdate = false; @@ -10167,8 +10320,13 @@ function renderWithHooks( return children; } function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; - workInProgress.flags &= ~(Passive | Update); + workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the + // complete phase (bubbleProperties). + + { + workInProgress.flags &= ~(Passive | Update); + } + current.lanes = removeLanes(current.lanes, lanes); } function resetHooksAfterThrow() { @@ -10319,6 +10477,8 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState @@ -10456,6 +10616,28 @@ function updateReducer(reducer, initialArg, init) { hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; + } // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + var interleavedLane = interleaved.lane; + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + interleavedLane + ); + markSkippedUpdateLanes(interleavedLane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (baseQueue === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.lanes = NoLanes; } var dispatch = queue.dispatch; @@ -10583,11 +10765,50 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { // // This can lead to tearing in the first renderer when it resumes, // but there's nothing we can do about that (short of throwing here and refusing to continue the render). - markSourceAsDirty(source); + markSourceAsDirty(source); // Intentioally throw an error to force React to retry synchronously. During + // the synchronous retry, it will block interleaved mutations, so we should + // get a consistent read. Therefore, the following error should never be + // visible to the user. + // + // If it were to become visible to the user, it suggests one of two things: + // a bug in React, or (more likely), a mutation during the render phase that + // caused the second re-render attempt to be different from the first. + // + // We know it's the second case if the logs are currently disabled. So in + // dev, we can present a more accurate error message. + + { + // eslint-disable-next-line react-internal/no-production-logging + if (console.log.__reactDisabledLog) { + // If the logs are disabled, this is the dev-only double render. This is + // only reachable if there was a mutation during render. Show a helpful + // error message. + // + // Something interesting to note: because we only double render in + // development, this error will never happen during production. This is + // actually true of all errors that occur during a double render, + // because if the first render had thrown, we would have exited the + // begin phase without double rendering. We should consider suppressing + // any error from a double render (with a warning) to more closely match + // the production behavior. + var componentName = getComponentNameFromFiber( + currentlyRenderingFiber$1 + ); + + { + throw Error( + "A mutable source was mutated while the " + + componentName + + " component was rendering. This is not supported. Move any mutations into event handlers or effects." + ); + } + } + } // We expect this error not to be thrown during the synchronous retry, + // because we blocked interleaved mutations. { throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } } @@ -10723,6 +10944,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { // including any interleaving updates that occur. var newQueue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -10770,6 +10993,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -10863,7 +11088,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); return; } } @@ -10886,7 +11111,9 @@ function mountEffect(create, deps) { } } - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + { + return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); + } } function updateEffect(create, deps) { @@ -10897,11 +11124,13 @@ function updateEffect(create, deps) { } } - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + return updateEffectImpl(Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + var fiberFlags = Update; + + return mountEffectImpl(fiberFlags, Layout, create, deps); } function updateLayoutEffect(create, deps) { @@ -10953,8 +11182,10 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; + var fiberFlags = Update; + return mountEffectImpl( - Update, + fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps @@ -11109,33 +11340,22 @@ function rerenderDeferredValue(value) { } function startTransition(setPending, callback) { - var priorityLevel = getCurrentPriorityLevel(); + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority( + higherEventPriority(previousPriority, ContinuousEventPriority) + ); + setPending(true); + var prevTransition = ReactCurrentBatchConfig$1.transition; + ReactCurrentBatchConfig$1.transition = 1; - { - runWithPriority( - priorityLevel < UserBlockingPriority$1 - ? UserBlockingPriority$1 - : priorityLevel, - function() { - setPending(true); - } - ); - runWithPriority( - priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, - function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = 1; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - } - ); - } -} + try { + setPending(false); + callback(); + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$1.transition = prevTransition; + } +} function mountTransition() { var _mountState2 = mountState(false), @@ -11145,7 +11365,7 @@ function mountTransition() { var start = startTransition.bind(null, setPending); var hook = mountWorkInProgressHook(); hook.memoizedState = start; - return [start, isPending]; + return [isPending, start]; } function updateTransition() { @@ -11154,7 +11374,7 @@ function updateTransition() { var hook = updateWorkInProgressHook(); var start = hook.memoizedState; - return [start, isPending]; + return [isPending, start]; } function rerenderTransition() { @@ -11163,7 +11383,7 @@ function rerenderTransition() { var hook = updateWorkInProgressHook(); var start = hook.memoizedState; - return [start, isPending]; + return [isPending, start]; } var isUpdatingOpaqueValueInRenderPhase = false; @@ -11176,7 +11396,7 @@ function getIsUpdatingOpaqueValueInRenderPhaseInDEV() { function warnOnOpaqueIdentifierAccessInDEV(fiber) { { // TODO: Should warn in effects and callbacks, too - var name = getComponentName(fiber.type) || "Unknown"; + var name = getComponentNameFromFiber(fiber) || "Unknown"; if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) { error( @@ -11233,19 +11453,7 @@ function dispatchAction(fiber, queue, action) { eagerReducer: null, eagerState: null, next: null - }; // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - queue.pending = update; + }; var alternate = fiber.alternate; if ( @@ -11256,7 +11464,47 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; } else { + if (isInterleavedUpdate(fiber)) { + var interleaved = queue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + queue.interleaved = update; + } else { + var _pending = queue.pending; + + if (_pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = _pending.next; + _pending.next = update; + } + + queue.pending = update; + } + if ( fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes) @@ -11309,7 +11557,24 @@ function dispatchAction(fiber, queue, action) { } } - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (isTransitionLane(lane) && root !== null) { + var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they + // must have finished. We can remove them from the shared queue, which + // represents a superset of the actually pending lanes. In some cases we + // may entangle more than we need to, but that's OK. In fact it's worse if + // we *don't* entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } } } @@ -11331,6 +11596,7 @@ var ContextOnlyDispatcher = { useOpaqueIdentifier: throwInvalidHookError, unstable_isNewReconciler: enableNewReconciler }; + var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; @@ -11359,8 +11625,8 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }; HooksDispatcherOnMountInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); + readContext: function(context) { + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; @@ -11368,10 +11634,10 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; checkDepsAreArrayDev(deps); return mountCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; mountHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11460,19 +11726,20 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnMountWithHookTypesInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); + readContext: function(context) { + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; updateHookTypesDev(); return mountCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11557,19 +11824,20 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnUpdateInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); + readContext: function(context) { + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; updateHookTypesDev(); return updateCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11654,19 +11922,20 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnRerenderInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); + readContext: function(context) { + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; updateHookTypesDev(); return updateCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11751,10 +12020,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnMountInDEV = { - readContext: function(context, observedBits) { + readContext: function(context) { warnInvalidContextAccess(); - return readContext(context, observedBits); + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; @@ -11762,11 +12032,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; mountHookTypesDev(); return mountCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; warnInvalidHookAccess(); mountHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11863,10 +12133,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnUpdateInDEV = { - readContext: function(context, observedBits) { + readContext: function(context) { warnInvalidContextAccess(); - return readContext(context, observedBits); + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; @@ -11874,11 +12145,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; updateHookTypesDev(); return updateCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; warnInvalidHookAccess(); updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -11975,10 +12246,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { - readContext: function(context, observedBits) { + readContext: function(context) { warnInvalidContextAccess(); - return readContext(context, observedBits); + return readContext(context); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; @@ -11986,11 +12258,11 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; updateHookTypesDev(); return updateCallback(callback, deps); }, - useContext: function(context, observedBits) { + useContext: function(context) { currentHookNameInDev = "useContext"; warnInvalidHookAccess(); updateHookTypesDev(); - return readContext(context, observedBits); + return readContext(context); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; @@ -12109,126 +12381,503 @@ function startProfilerTimer(fiber) { } } -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; -} +function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} + +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } +} + +function transferActualDuration(fiber) { + // Transfer time spent rendering these children so we don't lose it + // after we rerender. This is used as a helper in special cases + // where we should count the work of multiple passes. + var child = fiber.child; + + while (child) { + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } +} + +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; + +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} + +function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + if (current === null) { + // If this is a fresh new component that hasn't been rendered yet, we + // won't update its child set by applying minimal side-effects. Instead, + // we will add them all to the child before it gets rendered. That means + // we can optimize this reconciliation pass by not tracking side-effects. + workInProgress.child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + // If the current child is the same as the work in progress, it means that + // we haven't yet started any work on these children. Therefore, we use + // the clone algorithm to create a copy of all the current children. + // If we had any progressed work already, that is invalid at this point so + // let's throw it out. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + nextChildren, + renderLanes + ); + } +} + +function forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes +) { + // This function is fork of reconcileChildren. It's used in cases where we + // want to reconcile without matching against the existing set. This has the + // effect of all current children being unmounted; even if the type and key + // are the same, the old child is unmounted and a new child is created. + // + // To do this, we're going to go through the reconcile algorithm twice. In + // the first pass, we schedule a deletion for all the current children by + // passing null. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + null, + renderLanes + ); // In the second pass, we mount the new children. The trick here is that we + // pass null in place of where we usually pass the current child set. This has + // the effect of remounting all children regardless of whether their + // identities match. + + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); +} + +function updateForwardRef( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; + + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(Component) + ); + } + } + } + + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + + setIsRendering(false); + } + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateLanes, + renderLanes +) { + if (current === null) { + var type = Component.type; + + if ( + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined + ) { + var resolvedType = type; + + { + resolvedType = resolveFunctionForHotReloading(type); + } // If this is a plain function component without default props, + // and with only the default shallow comparison, we upgrade it + // to a SimpleMemoComponent to allow fast path updates. + + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + updateLanes, + renderLanes + ); + } + + { + var innerPropTypes = type.propTypes; + + if (innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(type) + ); + } + } + + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } + + { + var _type = Component.type; + var _innerPropTypes = _type.propTypes; + + if (_innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + _innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(_type) + ); + } + } + + var currentChild = current.child; // This is always exactly one child + + if (!includesSomeLane(updateLanes, renderLanes)) { + // This will be the props with resolved defaultProps, + // unlike current.memoizedProps which will be the unresolved ones. + var prevProps = currentChild.memoizedProps; // Default to shallow comparison + + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; + + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; +} + +function updateSimpleMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateLanes, + renderLanes +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens when the inner render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var outerMemoType = workInProgress.elementType; + + if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { + // We warn when you define propTypes on lazy() + // so let's just skip over it to find memo() outer wrapper. + // Inner props for memo are validated later. + var lazyComponent = outerMemoType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + + try { + outerMemoType = init(payload); + } catch (x) { + outerMemoType = null; + } // Inner propTypes will be validated in the function component path. + + var outerPropTypes = outerMemoType && outerMemoType.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentNameFromType(outerMemoType) + ); + } + } + } + } + + if (current !== null) { + var prevProps = current.memoizedProps; + + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type + ) { + didReceiveUpdate = false; + + if (!includesSomeLane(renderLanes, updateLanes)) { + // The pending lanes were cleared at the beginning of beginWork. We're + // about to bail out, but there might be other lanes that weren't + // included in the current render. Usually, the priority level of the + // remaining updates is accumlated during the evaluation of the + // component (i.e. when processing the update queue). But since since + // we're bailing out early *without* evaluating the component, we need + // to account for it here, too. Reset to the value of the current fiber. + // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, + // because a MemoComponent fiber does not have hooks or an update queue; + // rather, it wraps around an inner component, which may or may not + // contains hooks. + // TODO: Move the reset at in beginWork out of the common path so that + // this is no longer necessary. + workInProgress.lanes = current.lanes; + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + } + } + } + + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); +} + +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var prevState = current !== null ? current.memoizedState : null; // If this is not null, this is a cache pool that was carried over from the + // previous render. We will push this to the cache pool context so that we can + // resume in-flight requests. + + var spawnedCachePool = null; + + if ( + nextProps.mode === "hidden" || + nextProps.mode === "unstable-defer-without-hiding" + ) { + // Rendering a hidden tree. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + var nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = nextState; + pushRenderLanes(workInProgress, renderLanes); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. + var nextBaseLanes; + + if (prevState !== null) { + var prevBaseLanes = prevState.baseLanes; + nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); + } else { + nextBaseLanes = renderLanes; + } // Schedule this fiber to re-render at offscreen priority. Then bailout. + + workInProgress.lanes = workInProgress.childLanes = laneToLanes( + OffscreenLane + ); + var _nextState = { + baseLanes: nextBaseLanes, + cachePool: spawnedCachePool + }; + workInProgress.memoizedState = _nextState; + workInProgress.updateQueue = null; // We're about to bail out, but we need to push this to the stack anyway + // to avoid a push/pop misalignment. + + pushRenderLanes(workInProgress, nextBaseLanes); + + return null; + } else { + var _nextState2 = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. + + var subtreeRenderLanes = + prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); + } + } else { + // Rendering a visible tree. + var _subtreeRenderLanes; -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; + if (prevState !== null) { + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); - if (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; + workInProgress.memoizedState = null; + } else { + // We weren't previously hidden, and we still aren't, so there's nothing + // special to do. Need to push to the stack regardless, though, to avoid + // a push/pop misalignment. + _subtreeRenderLanes = renderLanes; } - profilerStartTime = -1; + pushRenderLanes(workInProgress, _subtreeRenderLanes); } -} -function transferActualDuration(fiber) { - // Transfer time spent rendering these children so we don't lose it - // after we rerender. This is used as a helper in special cases - // where we should count the work of multiple passes. - var child = fiber.child; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} // Note: These happen to have identical begin phases, for now. We shouldn't hold +// ourselves to this constraint, though. If the behavior diverges, we should +// fork the function. - while (child) { - fiber.actualDuration += child.actualDuration; - child = child.sibling; - } -} +var updateLegacyHiddenComponent = updateOffscreenComponent; -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; -var didReceiveUpdate = false; -var didWarnAboutBadClass; -var didWarnAboutModulePatternComponent; -var didWarnAboutContextTypeOnFunctionComponent; -var didWarnAboutGetDerivedStateOnFunctionComponent; -var didWarnAboutFunctionRefs; -var didWarnAboutReassigningProps; -var didWarnAboutRevealOrder; -var didWarnAboutTailOptions; +function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; +function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { - if (current === null) { - // If this is a fresh new component that hasn't been rendered yet, we - // won't update its child set by applying minimal side-effects. Instead, - // we will add them all to the child before it gets rendered. That means - // we can optimize this reconciliation pass by not tracking side-effects. - workInProgress.child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - } else { - // If the current child is the same as the work in progress, it means that - // we haven't yet started any work on these children. Therefore, we use - // the clone algorithm to create a copy of all the current children. - // If we had any progressed work already, that is invalid at this point so - // let's throw it out. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); +function updateProfiler(current, workInProgress, renderLanes) { + { + workInProgress.flags |= Update; } + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes -) { - // This function is fork of reconcileChildren. It's used in cases where we - // want to reconcile without matching against the existing set. This has the - // effect of all current children being unmounted; even if the type and key - // are the same, the old child is unmounted and a new child is created. - // - // To do this, we're going to go through the reconcile algorithm twice. In - // the first pass, we schedule a deletion for all the current children by - // passing null. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ); // In the second pass, we mount the new children. The trick here is that we - // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their - // identities match. +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; + } } -function updateForwardRef( +function updateFunctionComponent( current, workInProgress, Component, nextProps, renderLanes ) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens after the first render suspends. - // We'll need to figure out if this is fine or can cause issues. { if (workInProgress.type !== workInProgress.elementType) { // Lazy component props can't be validated in createElement @@ -12240,14 +12889,18 @@ function updateForwardRef( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentNameFromType(Component) ); } } } - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + var context; + + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } var nextChildren; prepareToReadContext(workInProgress, renderLanes); @@ -12258,9 +12911,9 @@ function updateForwardRef( nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); @@ -12277,407 +12930,432 @@ function updateForwardRef( return workInProgress.child; } -function updateMemoComponent( +function updateClassComponent( current, workInProgress, Component, nextProps, - updateLanes, renderLanes ) { - if (current === null) { - var type = Component.type; - - if ( - isSimpleFunctionComponent(type) && - Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. - Component.defaultProps === undefined - ) { - var resolvedType = type; - - { - resolvedType = resolveFunctionForHotReloading(type); - } // If this is a plain function component without default props, - // and with only the default shallow comparison, we upgrade it - // to a SimpleMemoComponent to allow fast path updates. - - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; - - { - validateFunctionComponentInDev(workInProgress, type); - } - - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - renderLanes - ); - } - - { - var innerPropTypes = type.propTypes; + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; if (innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. checkPropTypes( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(type) + getComponentNameFromType(Component) ); } } + } // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; + var hasContext; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; - if (_innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. - checkPropTypes( - _innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(_type) - ); - } + if (instance === null) { + if (current !== null) { + // A class component without an instance only mounts if it suspended + // inside a non-concurrent tree, in an inconsistent state. We want to + // treat it like a new mount, even though an empty version of it already + // committed. Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + + workInProgress.flags |= Placement; + } // In the initial pass we might need to construct the instance. + + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + shouldUpdate = true; + } else if (current === null) { + // In a resume, we'll already have an instance we can reuse. + shouldUpdate = resumeMountClassInstance( + workInProgress, + Component, + nextProps, + renderLanes + ); + } else { + shouldUpdate = updateClassInstance( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); } - var currentChild = current.child; // This is always exactly one child + var nextUnitOfWork = finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ); - if (!includesSomeLane(updateLanes, renderLanes)) { - // This will be the props with resolved defaultProps, - // unlike current.memoizedProps which will be the unresolved ones. - var prevProps = currentChild.memoizedProps; // Default to shallow comparison + { + var inst = workInProgress.stateNode; - var compare = Component.compare; - compare = compare !== null ? compare : shallowEqual; + if (shouldUpdate && inst.props !== nextProps) { + if (!didWarnAboutReassigningProps) { + error( + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentNameFromFiber(workInProgress) || "a component" + ); + } - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didWarnAboutReassigningProps = true; } - } // React DevTools reads this flag. + } - workInProgress.flags |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); - newChild.ref = workInProgress.ref; - newChild.return = workInProgress; - workInProgress.child = newChild; - return newChild; + return nextUnitOfWork; } -function updateSimpleMemoComponent( +function finishClassComponent( current, workInProgress, Component, - nextProps, - updateLanes, + shouldUpdate, + hasContext, renderLanes ) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens when the inner render suspends. - // We'll need to figure out if this is fine or can cause issues. - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var outerMemoType = workInProgress.elementType; + // Refs should update even if shouldComponentUpdate returns false + markRef(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; - if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { - // We warn when you define propTypes on lazy() - // so let's just skip over it to find memo() outer wrapper. - // Inner props for memo are validated later. - var lazyComponent = outerMemoType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + if (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); + } - try { - outerMemoType = init(payload); - } catch (x) { - outerMemoType = null; - } // Inner propTypes will be validated in the function component path. + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } - var outerPropTypes = outerMemoType && outerMemoType.propTypes; + var instance = workInProgress.stateNode; // Rerender - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentName(outerMemoType) - ); - } - } - } - } + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; - if (current !== null) { - var prevProps = current.memoizedProps; + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type - ) { - didReceiveUpdate = false; + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); - if (!includesSomeLane(renderLanes, updateLanes)) { - // The pending lanes were cleared at the beginning of beginWork. We're - // about to bail out, but there might be other lanes that weren't - // included in the current render. Usually, the priority level of the - // remaining updates is accumlated during the evaluation of the - // component (i.e. when processing the update queue). But since since - // we're bailing out early *without* evaluating the component, we need - // to account for it here, too. Reset to the value of the current fiber. - // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, - // because a MemoComponent fiber does not have hooks or an update queue; - // rather, it wraps around an inner component, which may or may not - // contains hooks. - // TODO: Move the reset at in beginWork out of the common path so that - // this is no longer necessary. - workInProgress.lanes = current.lanes; - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } + setIsRendering(false); } - } + } // React DevTools reads this flag. - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); -} + workInProgress.flags |= PerformedWork; -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - var prevState = current !== null ? current.memoizedState : null; + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. - if ( - nextProps.mode === "hidden" || - nextProps.mode === "unstable-defer-without-hiding" - ) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy sync mode, don't defer the subtree. Render it now. - // TODO: Figure out what we should do in Blocking mode. - var nextState = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = nextState; - pushRenderLanes(workInProgress, renderLanes); - } else if (!includesSomeLane(renderLanes, OffscreenLane)) { - var nextBaseLanes; + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. - if (prevState !== null) { - var prevBaseLanes = prevState.baseLanes; - nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); - } else { - nextBaseLanes = renderLanes; - } // Schedule this fiber to re-render at offscreen priority. Then bailout. + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); + } - { - markSpawnedWork(OffscreenLane); - } + return workInProgress.child; +} - workInProgress.lanes = workInProgress.childLanes = laneToLanes( - OffscreenLane - ); - var _nextState = { - baseLanes: nextBaseLanes - }; - workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway - // to avoid a push/pop misalignment. +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; - pushRenderLanes(workInProgress, nextBaseLanes); - return null; - } else { - // Rendering at offscreen, so we can clear the base lanes. - var _nextState2 = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. + if (root.pendingContext) { + pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); + } - var subtreeRenderLanes = - prevState !== null ? prevState.baseLanes : renderLanes; - pushRenderLanes(workInProgress, subtreeRenderLanes); - } - } else { - var _subtreeRenderLanes; + pushHostContainer(workInProgress, root.containerInfo); +} - if (prevState !== null) { - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; + + if (!(current !== null && updateQueue !== null)) { + throw Error( + "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." + ); + } + + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState.element; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; + var root = workInProgress.stateNode; + // being called "element". - workInProgress.memoizedState = null; - } else { - // We weren't previously hidden, and we still aren't, so there's nothing - // special to do. Need to push to the stack regardless, though, to avoid - // a push/pop misalignment. - _subtreeRenderLanes = renderLanes; - } + var nextChildren = nextState.element; - pushRenderLanes(workInProgress, _subtreeRenderLanes); + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} // Note: These happen to have identical begin phases, for now. We shouldn't hold -// ourselves to this constraint, though. If the behavior diverges, we should -// fork the function. + if (root.hydrate && enterHydrationState()) { + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + workInProgress.child = child; + var node = child; -var updateLegacyHiddenComponent = updateOffscreenComponent; + while (node) { + // Mark each child as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + node.flags = (node.flags & ~Placement) | Hydrating; + node = node.sibling; + } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } -function updateFragment(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function updateMode(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} +function updateHostComponent(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); -function updateProfiler(current, workInProgress, renderLanes) { - { - workInProgress.flags |= Update; // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, + var type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + if (prevProps !== null && shouldSetTextContent()) { + // If we're switching from a direct text child to a normal child, or to + // empty, we need to schedule the text content to be reset. + workInProgress.flags |= ContentReset; } - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; + markRef(current, workInProgress); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef(current, workInProgress) { - var ref = workInProgress.ref; +function updateHostText(current, workInProgress) { + // immediately after. - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } + return null; } -function updateFunctionComponent( - current, +function mountLazyComponent( + _current, workInProgress, - Component, - nextProps, + elementType, + updateLanes, renderLanes ) { - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + if (_current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) + workInProgress.flags |= Placement; + } + + var props = workInProgress.pendingProps; + var lazyComponent = elementType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + var Component = init(payload); // Store the unwrapped component in the type. + + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; + + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component + ); + } + + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component ); } + + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; } - } - var context; + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component + ); + } - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes - ); + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentNameFromType(Component) + ); + } + } + } - setIsRendering(false); + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateLanes, + renderLanes + ); + return child; + } } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. + var hint = ""; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } } -function updateClassComponent( - current, +function mountIncompleteClassComponent( + _current, workInProgress, Component, nextProps, renderLanes ) { - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; - - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } - } // Push context providers early to prevent context stack mismatches. + if (_current !== null) { + // An incomplete component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + + workInProgress.flags |= Placement; + } // Promote the fiber to a class and try rendering again. + + workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` + // Push context providers early to prevent context stack mismatches. // During mounting we don't know the child context yet as the instance doesn't exist. // We will invalidate the child context in finishClassComponent() right after rendering. @@ -12691,2184 +13369,2589 @@ function updateClassComponent( } prepareToReadContext(workInProgress, renderLanes); - var instance = workInProgress.stateNode; - var shouldUpdate; - - if (instance === null) { - if (current !== null) { - // A class component without an instance only mounts if it suspended - // inside a non-concurrent tree, in an inconsistent state. We want to - // treat it like a new mount, even though an empty version of it already - // committed. Disconnect the alternate pointers. - current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. - - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - shouldUpdate = true; - } else if (current === null) { - // In a resume, we'll already have an instance we can reuse. - shouldUpdate = resumeMountClassInstance( - workInProgress, - Component, - nextProps, - renderLanes - ); - } else { - shouldUpdate = updateClassInstance( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); - } - - var nextUnitOfWork = finishClassComponent( - current, + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, workInProgress, Component, - shouldUpdate, + true, hasContext, renderLanes ); - - { - var inst = workInProgress.stateNode; - - if (shouldUpdate && inst.props !== nextProps) { - if (!didWarnAboutReassigningProps) { - error( - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" - ); - } - - didWarnAboutReassigningProps = true; - } - } - - return nextUnitOfWork; } -function finishClassComponent( - current, +function mountIndeterminateComponent( + _current, workInProgress, Component, - shouldUpdate, - hasContext, renderLanes ) { - // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); - var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; + if (_current !== null) { + // An indeterminate component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } + workInProgress.flags |= Placement; + } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + var props = workInProgress.pendingProps; + var context; + + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); } - var instance = workInProgress.stateNode; // Rerender + prepareToReadContext(workInProgress, renderLanes); + var value; - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentNameFromType(Component) || "Unknown"; - if ( - didCaptureError && - typeof Component.getDerivedStateFromError !== "function" - ) { - // If we captured an error, but getDerivedStateFromError is not defined, - // unmount all the children. componentDidCatch will schedule an update to - // re-render a fallback. This is temporary until we migrate everyone to - // the new API. - // TODO: Warn in a future release. - nextChildren = null; + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName + ); - { - stopProfilerTimerIfRunning(); + didWarnAboutBadClass[componentName] = true; + } } - } else { - { - setIsRendering(true); - nextChildren = instance.render(); - setIsRendering(false); + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); } - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; - if (current !== null && didCaptureError) { - // If we're recovering from an error, reconcile without reusing any of - // the existing children. Conceptually, the normal children and the children - // that are shown on error are two different sets, so we shouldn't reuse - // normal children even if their identities match. - forceUnmountCurrentAndReconcile( - current, + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, workInProgress, - nextChildren, + Component, + props, + context, renderLanes ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } // Memoize state using the values we just used to render. - // TODO: Restructure so we never read values from the instance. + setIsRendering(false); + } // React DevTools reads this flag. - workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + workInProgress.flags |= PerformedWork; - if (hasContext) { - invalidateContextProvider(workInProgress, Component, true); + { + // Support for module components is deprecated and is removed behind a flag. + // Whether or not it would crash later, we want to show a good message in DEV first. + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + var _componentName = getComponentNameFromType(Component) || "Unknown"; + + if (!didWarnAboutModulePatternComponent[_componentName]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName, + _componentName, + _componentName + ); + + didWarnAboutModulePatternComponent[_componentName] = true; + } + } } - return workInProgress.child; -} + if ( + // Run these checks in production only if the flag is off. + // Eventually we'll delete this branch altogether. + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + { + var _componentName2 = getComponentNameFromType(Component) || "Unknown"; -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; + if (!didWarnAboutModulePatternComponent[_componentName2]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName2, + _componentName2, + _componentName2 + ); - if (root.pendingContext) { - pushTopLevelContextObject( + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance + + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext = false; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } + + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent( + null, workInProgress, - root.pendingContext, - root.pendingContext !== root.context + Component, + true, + hasContext, + renderLanes ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, false); - } + } else { + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; - pushHostContainer(workInProgress, root.containerInfo); -} + reconcileChildren(null, workInProgress, value, renderLanes); -function updateHostRoot(current, workInProgress, renderLanes) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + { + validateFunctionComponentInDev(workInProgress, Component); + } - if (!(current !== null && updateQueue !== null)) { - throw Error( - "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." - ); + return workInProgress.child; } +} - var nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property - // being called "element". +function validateFunctionComponentInDev(workInProgress, Component) { + { + if (Component) { + if (Component.childContextTypes) { + error( + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ); + } + } - var nextChildren = nextState.element; + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - var root = workInProgress.stateNode; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - while (node) { - // Mark each child as hydrating. This is a fast path to know whether this - // tree is part of a hydrating tree. This is used to determine if a child - // node has fully mounted yet, and for scheduling event replaying. - // Conceptually this is similar to Placement in that a new subtree is - // inserted into the React tree here. It just happens to not need DOM - // mutations because it already exists. - node.flags = (node.flags & ~Placement) | Hydrating; - node = node.sibling; + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } } - } else { - // Otherwise reset hydration state in case we aborted and resumed another - // root. - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } - return workInProgress.child; -} + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentNameFromType(Component) || "Unknown"; -function updateHostComponent(current, workInProgress, renderLanes) { - pushHostContext(workInProgress); + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 + ); - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } + } - if (prevProps !== null && shouldSetTextContent()) { - // If we're switching from a direct text child to a normal child, or to - // empty, we need to schedule the text content to be reset. - workInProgress.flags |= ContentReset; - } + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentNameFromType(Component) || "Unknown"; - markRef(current, workInProgress); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error( + "%s: Function components do not support contextType.", + _componentName4 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } + } + } } -function updateHostText(current, workInProgress) { - // immediately after. +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; - return null; +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCachePool() + }; } -function mountLazyComponent( - _current, +function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; + + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool + }; +} // TODO: Probably should inline this back + +function shouldRemainOnFallback( + suspenseContext, + current, workInProgress, - elementType, - updateLanes, renderLanes ) { - if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + // If we're already showing a fallback, there are cases where we need to + // remain on that fallback regardless of whether the content has resolved. + // For example, SuspenseList coordinates when nested content appears. + if (current !== null) { + var suspenseState = current.memoizedState; - workInProgress.flags |= Placement; - } + if (suspenseState === null) { + // Currently showing content. Don't hide it, even if ForceSuspenseFallack + // is true. More precise name might be "ForceRemainSuspenseFallback". + // Note: This is a factoring smell. Can't remain on a fallback if there's + // no fallback to remain on. + return false; + } + } // Not currently showing content. Consult the Suspense context. - var props = workInProgress.pendingProps; - var lazyComponent = elementType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; - var Component = init(payload); // Store the unwrapped component in the type. + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); +} - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); +} - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + + { + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; + } + } + + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + + if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + showFallback = true; + workInProgress.flags &= ~DidCapture; + } else { + // Attempting the main content + if (current === null || current.memoizedState !== null) { + // This is a new mount or this boundary is already showing a fallback state. + // Mark this subtree context as having at least one invisible parent that could + // handle the fallback state. + // Boundaries without fallbacks or should be avoided are not considered since + // they cannot handle preferred fallback states. + if ( + nextProps.fallback !== undefined && + nextProps.unstable_avoidThisFallback !== true + ) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext ); } + } + } - child = updateFunctionComponent( - null, + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense + // boundary's children. This involves some custom reconcilation logic. Two + // main reasons this is so complicated. + // + // First, Legacy Mode has different semantics for backwards compatibility. The + // primary tree will commit in an inconsistent state, so when we do the + // second pass to render the fallback, we do some exceedingly, uh, clever + // hacks to make that not totally break. Like transferring effects and + // deletions from hidden tree. In Concurrent Mode, it's much simpler, + // because we bailout on the primary tree completely and leave it in its old + // state, no effects. Same as what we do for Offscreen (except that + // Offscreen doesn't have the first render pass). + // + // Second is hydration. During hydration, the Suspense fiber has a slightly + // different layout, where the child points to a dehydrated fragment, which + // contains the DOM rendered by the server. + // + // Third, even if you set all that aside, Suspense is like error boundaries in + // that we first we try to render one tree, and if that fails, we render again + // and switch to a different tree. Like a try/catch block. So we have to track + // which branch we're currently rendering. Ideally we would model this using + // a stack. + + if (current === null) { + // Initial mount + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined); + + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } - - child = updateClassComponent( - null, + var primaryChildFragment = workInProgress.child; + primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackFragment; + } else if (typeof nextProps.unstable_expectedLoadTime === "number") { + // This is a CPU-bound tree. Skip this tree and show a placeholder to + // unblock the surrounding content. Then immediately retry after the + // initial commit. + var _fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - case ForwardRef: { - { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component - ); - } + var _primaryChildFragment = workInProgress.child; + _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to + // get it started back up to attempt the next item. While in terms of + // priority this work has the same priority as this current render, it's + // not part of the same transition once the transition has committed. If + // it's sync, we still want to yield so that it can be painted. + // Conceptually, this is really the same as pinging. We can use any + // RetryLane even if it's the one currently rendering since we're leaving + // it behind on this node. - child = updateForwardRef( - null, + workInProgress.lanes = SomeRetryLane; + return _fallbackFragment; + } else { + return mountSuspensePrimaryChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, renderLanes ); - return child; } + } else { + // This is an update. + // If the current fiber has a SuspenseState, that means it's already showing + // a fallback. + var prevState = current.memoizedState; - case MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentName(Component) - ); - } - } + var _fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren2, + _nextFallbackChildren2, + renderLanes + ); + + var _primaryChildFragment3 = workInProgress.child; + var prevOffscreenState = current.child.memoizedState; + _primaryChildFragment3.memoizedState = + prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); + _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree( + current, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment; + } else { + var _nextPrimaryChildren3 = nextProps.children; + + var _primaryChildFragment4 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren3, + renderLanes + ); + + workInProgress.memoizedState = null; + return _primaryChildFragment4; } + } else { + // The current tree is not already showing a fallback. + if (showFallback) { + // Timed out. + var _nextFallbackChildren3 = nextProps.fallback; + var _nextPrimaryChildren4 = nextProps.children; - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, - renderLanes - ); - return child; + var _fallbackChildFragment2 = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren4, + _nextFallbackChildren3, + renderLanes + ); + + var _primaryChildFragment5 = workInProgress.child; + var _prevOffscreenState = current.child.memoizedState; + _primaryChildFragment5.memoizedState = + _prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); + _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree( + current, + renderLanes + ); // Skip the primary children, and continue working on the + // fallback children. + + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment2; + } else { + // Still haven't timed out. Continue rendering the children, like we + // normally do. + var _nextPrimaryChildren5 = nextProps.children; + + var _primaryChildFragment6 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren5, + renderLanes + ); + + workInProgress.memoizedState = null; + return _primaryChildFragment6; + } } } +} - var hint = ""; +function mountSuspensePrimaryChildren( + workInProgress, + primaryChildren, + renderLanes +) { + var mode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + renderLanes, + null + ); + primaryChildFragment.return = workInProgress; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; +function mountSuspenseFallbackChildren( + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + var fallbackChildFragment; + + if ( + (mode & ConcurrentMode) === NoMode && + progressedPrimaryFragment !== null + ) { + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; + + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = 0; + primaryChildFragment.treeBaseDuration = 0; } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } else { + primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + NoLanes, + null + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null ); } + + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; } -function mountIncompleteClassComponent( - _current, +function createWorkInProgressOffscreenFiber(current, offscreenProps) { + // The props argument to `createWorkInProgress` is `any` typed, so we use this + // wrapper function to constrain it. + return createWorkInProgress(current, offscreenProps); +} + +function updateSuspensePrimaryChildren( + current, workInProgress, - Component, - nextProps, + primaryChildren, renderLanes ) { - if (_current !== null) { - // An incomplete component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren + } + ); - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; + } - workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` - // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - var hasContext; + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); + } } - prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); + workInProgress.child = primaryChildFragment; + return primaryChildFragment; } -function mountIndeterminateComponent( - _current, +function updateSuspenseFallbackChildren( + current, workInProgress, - Component, + primaryChildren, + fallbackChildren, renderLanes ) { - if (_current !== null) { - // An indeterminate component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } - - var props = workInProgress.pendingProps; - var context; - - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); - context = getMaskedContext(workInProgress, unmaskedContext); - } + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; - prepareToReadContext(workInProgress, renderLanes); - var value; + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was + // already cloned. In legacy mode, the only case where this isn't true is + // when DevTools forces us to display a fallback; we skip the first render + // pass entirely and go straight to rendering the fallback. (In Concurrent + // Mode, SuspenseList can also trigger this scenario, but this is a legacy- + // only codepath.) + workInProgress.child !== currentPrimaryChildFragment + ) { + var progressedPrimaryFragment = workInProgress.child; + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; - { - if ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = + currentPrimaryChildFragment.selfBaseDuration; + primaryChildFragment.treeBaseDuration = + currentPrimaryChildFragment.treeBaseDuration; + } // The fallback fiber was added as a deletion during the first pass. + // However, since we're going to remain on the fallback, we no longer want + // to delete it. - if (!didWarnAboutBadClass[componentName]) { - error( - "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + - "This is likely to cause errors. Change %s to extend React.Component instead.", - componentName, - componentName - ); + workInProgress.deletions = null; + } else { + primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + primaryChildProps + ); // Since we're reusing a current tree, we need to reuse the flags, too. + // (We don't do this in legacy mode, because in legacy mode we don't re-use + // the current tree; see previous branch.) - didWarnAboutBadClass[componentName] = true; - } - } + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } + var fallbackChildFragment; - setIsRendering(true); - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes + if (currentFallbackChildFragment !== null) { + fallbackChildFragment = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren ); - setIsRendering(false); - } // React DevTools reads this flag. + } else { + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. - workInProgress.flags |= PerformedWork; + fallbackChildFragment.flags |= Placement; + } - { - // Support for module components is deprecated and is removed behind a flag. - // Whether or not it would crash later, we want to show a good message in DEV first. - if ( - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - var _componentName = getComponentName(Component) || "Unknown"; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - if (!didWarnAboutModulePatternComponent[_componentName]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName, - _componentName, - _componentName - ); +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; - didWarnAboutModulePatternComponent[_componentName] = true; - } - } + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); } - if ( - // Run these checks in production only if the flag is off. - // Eventually we'll delete this branch altogether. - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - { - var _componentName2 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutModulePatternComponent[_componentName2]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName2, - _componentName2, - _componentName2 - ); - - didWarnAboutModulePatternComponent[_componentName2] = true; - } - } // Proceed under the assumption that this is a class instance + scheduleWorkOnParentPath(fiber.return, renderLanes); +} - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderLanes +) { + // Mark any Suspense boundaries with fallbacks as having work to do. + // If they were previously forced into fallbacks, they may now be able + // to unblock. + var node = firstChild; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - var hasContext = false; + if (state !== null) { + scheduleWorkOnFiber(node, renderLanes); + } + } else if (node.tag === SuspenseListComponent) { + // If the tail is hidden there might not be an Suspense boundaries + // to schedule work on. In this case we have to schedule it on the + // list itself. + // We don't have to traverse to the children of the list since + // the list will propagate the change when it rerenders. + scheduleWorkOnFiber(node, renderLanes); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + if (node === workInProgress) { + return; } - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); + node = node.return; } - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); - } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; + node.sibling.return = node.return; + node = node.sibling; + } +} - reconcileChildren(null, workInProgress, value, renderLanes); +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; - { - validateFunctionComponentInDev(workInProgress, Component); + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; } - return workInProgress.child; + row = row.sibling; } + + return lastContentRow; } -function validateFunctionComponentInDev(workInProgress, Component) { +function validateRevealOrder(revealOrder) { { - if (Component) { - if (Component.childContextTypes) { - error( - "%s(...): childContextTypes cannot be defined on a function component.", - Component.displayName || Component.name || "Component" - ); - } - } + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + break; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + case "forward": + case "backward": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + break; + } - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder ); } } + } +} - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentName(Component) || "Unknown"; +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 + '"%s" is not a supported value for tail on . ' + + 'Did you mean "collapsed" or "hidden"?', + tailMode ); + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } - } - - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName4 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { error( - "%s: Function components do not support contextType.", - _componentName4 + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode ); - - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; } } } } -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; - -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes - }; -} +function validateSuspenseListNestedChild(childSlot, index) { + { + var isAnArray = isArray(childSlot); + var isIterable = + !isAnArray && typeof getIteratorFn(childSlot) === "function"; -function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { - return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) - }; -} // TODO: Probably should inline this back + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; -function shouldRemainOnFallback( - suspenseContext, - current, - workInProgress, - renderLanes -) { - // If we're already showing a fallback, there are cases where we need to - // remain on that fallback regardless of whether the content has resolved. - // For example, SuspenseList coordinates when nested content appears. - if (current !== null) { - var suspenseState = current.memoizedState; + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); - if (suspenseState === null) { - // Currently showing content. Don't hide it, even if ForceSuspenseFallack - // is true. More precise name might be "ForceRemainSuspenseFallback". - // Note: This is a factoring smell. Can't remain on a fallback if there's - // no fallback to remain on. return false; } - } // Not currently showing content. Consult the Suspense context. + } - return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); + return true; } -function getRemainingWorkInPrimaryTree(current, renderLanes) { - // TODO: Should not remove render lanes that were pinged during this render - return removeLanes(current.childLanes, renderLanes); -} +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; + } + } + } else { + var iteratorFn = getIteratorFn(children); -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - { - if (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + + _i++; + } + } + } else { + error( + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); + } + } } } +} - var suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { - // Something in this boundary's subtree already suspended. Switch to - // rendering the fallback children. - showFallback = true; - workInProgress.flags &= ~DidCapture; + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }; } else { - // Attempting the main content - if (current === null || current.memoizedState !== null) { - // This is a new mount or this boundary is already showing a fallback state. - // Mark this subtree context as having at least one invisible parent that could - // handle the fallback state. - // Boundaries without fallbacks or should be avoided are not considered since - // they cannot handle preferred fallback states. - if ( - nextProps.fallback !== undefined && - nextProps.unstable_avoidThisFallback !== true - ) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext - ); - } - } + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.renderingStartTime = 0; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailMode = tailMode; } +} // This can end up rendering this component multiple passes. +// The first pass splits the children fibers into two sets. A head and tail. +// We first render the head. If anything is in fallback state, we do another +// pass through beginWork to rerender all children (including the tail) with +// the force suspend context. If the first render didn't have anything in +// in fallback state. Then we render each row in the tail one-by-one. +// That happens in the completeWork phase without going back to beginWork. - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense - // boundary's children. This involves some custom reconcilation logic. Two - // main reasons this is so complicated. - // - // First, Legacy Mode has different semantics for backwards compatibility. The - // primary tree will commit in an inconsistent state, so when we do the - // second pass to render the fallback, we do some exceedingly, uh, clever - // hacks to make that not totally break. Like transferring effects and - // deletions from hidden tree. In Concurrent Mode, it's much simpler, - // because we bailout on the primary tree completely and leave it in its old - // state, no effects. Same as what we do for Offscreen (except that - // Offscreen doesn't have the first render pass). - // - // Second is hydration. During hydration, the Suspense fiber has a slightly - // different layout, where the child points to a dehydrated fragment, which - // contains the DOM rendered by the server. - // - // Third, even if you set all that aside, Suspense is like error boundaries in - // that we first we try to render one tree, and if that fails, we render again - // and switch to a different tree. Like a try/catch block. So we have to track - // which branch we're currently rendering. Ideally we would model this using - // a stack. - - if (current === null) { - // Initial mount - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); +function updateSuspenseListComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var revealOrder = nextProps.revealOrder; + var tailMode = nextProps.tail; + var newChildren = nextProps.children; + validateRevealOrder(revealOrder); + validateTailOptions(tailMode, revealOrder); + validateSuspenseListChildren(newChildren, revealOrder); + reconcileChildren(current, workInProgress, newChildren, renderLanes); + var suspenseContext = suspenseStackCursor.current; + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags; - if (showFallback) { - var fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); - var primaryChildFragment = workInProgress.child; - primaryChildFragment.memoizedState = mountSuspenseOffscreenState( - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return fallbackFragment; - } else if (typeof nextProps.unstable_expectedLoadTime === "number") { - // This is a CPU-bound tree. Skip this tree and show a placeholder to - // unblock the surrounding content. Then immediately retry after the - // initial commit. - var _fallbackFragment = mountSuspenseFallbackChildren( + 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, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); - - var _primaryChildFragment = workInProgress.child; - _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + workInProgress.child, renderLanes ); - workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to - // get it started back up to attempt the next item. While in terms of - // priority this work has the same priority as this current render, it's - // not part of the same transition once the transition has committed. If - // it's sync, we still want to yield so that it can be painted. - // Conceptually, this is really the same as pinging. We can use any - // RetryLane even if it's the one currently rendering since we're leaving - // it behind on this node. + } - workInProgress.lanes = SomeRetryLane; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - { - markSpawnedWork(SomeRetryLane); - } + pushSuspenseContext(workInProgress, suspenseContext); - return _fallbackFragment; - } else { - return mountSuspensePrimaryChildren( - workInProgress, - nextPrimaryChildren, - renderLanes - ); - } + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy mode, SuspenseList doesn't work so we just + // use make it a noop by treating it as the default revealOrder. + workInProgress.memoizedState = null; } else { - // This is an update. - // If the current fiber has a SuspenseState, that means it's already showing - // a fallback. - var prevState = current.memoizedState; + switch (revealOrder) { + case "forwards": { + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; - if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; + 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; + } - var _fallbackChildFragment = updateSuspenseFallbackChildren( - current, + initSuspenseListRenderState( workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, - renderLanes + false, // isBackwards + tail, + lastContentRow, + tailMode ); + break; + } - var _primaryChildFragment3 = workInProgress.child; - var prevOffscreenState = current.child.memoizedState; - _primaryChildFragment3.memoizedState = - prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); - _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes + 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 ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment; - } else { - var _nextPrimaryChildren3 = nextProps.children; + break; + } - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, + case "together": { + initSuspenseListRenderState( workInProgress, - _nextPrimaryChildren3, - renderLanes + false, // isBackwards + null, // tail + null, // last + undefined ); + break; + } + default: { + // The default reveal order is the same as not having + // a boundary. workInProgress.memoizedState = null; - return _primaryChildFragment4; } - } else { - // The current tree is not already showing a fallback. - if (showFallback) { - // Timed out. - var _nextFallbackChildren3 = nextProps.fallback; - var _nextPrimaryChildren4 = nextProps.children; + } + } - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes - ); + return workInProgress.child; +} - var _primaryChildFragment5 = workInProgress.child; - var _prevOffscreenState = current.child.memoizedState; - _primaryChildFragment5.memoizedState = - _prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); - _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); // Skip the primary children, and continue working on the - // fallback children. +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment2; - } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - var _nextPrimaryChildren5 = nextProps.children; + if (current === null) { + // Portals are special because we don't append the children during mount + // but at commit. Therefore we need to track insertions which the normal + // flow doesn't do during mount. This doesn't happen at the root because + // the root always starts with a "current" with a null child. + // TODO: Consider unifying this with how the root works. + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } - var _primaryChildFragment6 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren5, - renderLanes + return workInProgress.child; +} + +var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + +function updateContextProvider(current, workInProgress, renderLanes) { + var providerType = workInProgress.type; + var context = providerType._context; + var newProps = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + var newValue = newProps.value; + + { + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; + + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" ); + } + } - workInProgress.memoizedState = null; - return _primaryChildFragment6; + var providerPropTypes = workInProgress.type.propTypes; + + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + } + } + + pushProvider(workInProgress, context, newValue); + + { + if (oldProps !== null) { + var oldValue = oldProps.value; + + if (objectIs(oldValue, newValue)) { + // No change. Bailout early if children are the same. + if (oldProps.children === newProps.children && !hasContextChanged()) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + } else { + // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange(workInProgress, context, renderLanes); } } } -} -function mountSuspensePrimaryChildren( - workInProgress, - primaryChildren, - renderLanes -) { - var mode = workInProgress.mode; - var primaryChildProps = { - mode: "visible", - children: primaryChildren - }; - var primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - renderLanes, - null - ); - primaryChildFragment.return = workInProgress; - workInProgress.child = primaryChildFragment; - return primaryChildFragment; + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; } -function mountSuspenseFallbackChildren( - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; +var hasWarnedAboutUsingContextAsConsumer = false; - if ((mode & BlockingMode) === NoMode && progressedPrimaryFragment !== null) { - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; +function updateContextConsumer(current, workInProgress, renderLanes) { + var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In + // DEV mode, we create a separate object for Context.Consumer that acts + // like a proxy to Context. This proxy object adds unnecessary code in PROD + // so we use the old behaviour (Context.Consumer references Context) to + // reduce size and overhead. The separate object references context via + // a property called "_context", which also gives us the ability to check + // in DEV mode if this property exists or not and warn if it does not. - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = 0; - primaryChildFragment.treeBaseDuration = 0; + { + if (context._context === undefined) { + // This may be because it's a Context (rather than a Consumer). + // Or it may be because it's older React where they're the same thing. + // We only want to warn if we're sure it's a new React. + if (context !== context.Consumer) { + if (!hasWarnedAboutUsingContextAsConsumer) { + hasWarnedAboutUsingContextAsConsumer = true; + + error( + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); + } + } + } else { + context = context._context; } + } - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); - } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null - ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + var newProps = workInProgress.pendingProps; + var render = newProps.children; + + { + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } } - primaryChildFragment.return = workInProgress; - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context); + var newChildren; + + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; } -function createWorkInProgressOffscreenFiber(current, offscreenProps) { - // The props argument to `createWorkInProgress` is `any` typed, so we use this - // wrapper function to constrain it. - return createWorkInProgress(current, offscreenProps); +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; } -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } + + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } + + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. + + if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { + // The children don't have any work either. We can skip them. + // TODO: Once we add back resuming, we should check if the children are + // a work-in-progress set. If so, we need to transfer their effects. { - mode: "visible", - children: primaryChildren + return null; } - ); + } // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. - if ((workInProgress.mode & BlockingMode) === NoMode) { - primaryChildFragment.lanes = renderLanes; - } + cloneChildFibers(current, workInProgress); + return workInProgress.child; +} - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = null; +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - if (currentFallbackChildFragment !== null) { - // Delete the fallback child fragment - currentFallbackChildFragment.nextEffect = null; - currentFallbackChildFragment.flags = Deletion; - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; - } + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - workInProgress.child = primaryChildFragment; - return primaryChildFragment; -} + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. -function updateSuspenseFallbackChildren( - current, - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & BlockingMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was - // already cloned. In legacy mode, the only case where this isn't true is - // when DevTools forces us to display a fallback; we skip the first render - // pass entirely and go straight to rendering the fallback. (In Concurrent - // Mode, SuspenseList can also trigger this scenario, but this is a legacy- - // only codepath.) - workInProgress.child !== currentPrimaryChildFragment - ) { - var progressedPrimaryFragment = workInProgress.child; - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration; - primaryChildFragment.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration; - } // The fallback fiber was added as a deletion effect during the first pass. - // However, since we're going to remain on the fallback, we no longer want - // to delete it. So we need to remove it from the list. Deletions are stored - // on the same list as effects. We want to keep the effects from the primary - // tree. So we copy the primary child fragment's effect list, which does not - // include the fallback deletion effect. + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } + + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); + } + } + + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. - var progressedLastEffect = primaryChildFragment.lastEffect; + var deletions = returnFiber.deletions; - if (progressedLastEffect !== null) { - workInProgress.firstEffect = primaryChildFragment.firstEffect; - workInProgress.lastEffect = progressedLastEffect; - progressedLastEffect.nextEffect = null; + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; } else { - // TODO: Reset this somewhere else? Lol legacy mode is so weird. - workInProgress.firstEffect = workInProgress.lastEffect = null; + deletions.push(current); } - } else { - primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - primaryChildProps - ); - } - - var fallbackChildFragment; - if (currentFallbackChildFragment !== null) { - fallbackChildFragment = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - ); - } else { - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); // Needs a placement effect because the parent (the Suspense boundary) already - // mounted but this is a new fiber. + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. - fallbackChildFragment.flags |= Placement; + return newWorkInProgress; } - - fallbackChildFragment.return = workInProgress; - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; } -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; +function beginWork(current, workInProgress, renderLanes) { + var updateLanes = workInProgress.lanes; - if (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + { + if (workInProgress._debugNeedsRemount && current !== null) { + // This will restart the begin phase with a new fiber. + return remountFiber( + current, + workInProgress, + createFiberFromTypeAndProps( + workInProgress.type, + workInProgress.key, + workInProgress.pendingProps, + workInProgress._debugOwner || null, + workInProgress.mode, + workInProgress.lanes + ) + ); + } } - scheduleWorkOnParentPath(fiber.return, renderLanes); -} + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; -function propagateSuspenseContextChange( - workInProgress, - firstChild, - renderLanes -) { - // Mark any Suspense boundaries with fallbacks as having work to do. - // If they were previously forced into fallbacks, they may now be able - // to unblock. - var node = firstChild; + if ( + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type + ) { + // If props or context changed, mark the fiber as having performed work. + // This may be unset if the props are determined to be equal later (memo). + didReceiveUpdate = true; + } else if (!includesSomeLane(renderLanes, updateLanes)) { + didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering + // the begin phase. There's still some bookkeeping we that needs to be done + // in this optimized path, mostly pushing stuff onto the stack. - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; - if (state !== null) { - scheduleWorkOnFiber(node, renderLanes); - } - } else if (node.tag === SuspenseListComponent) { - // If the tail is hidden there might not be an Suspense boundaries - // to schedule work on. In this case we have to schedule it on the - // list itself. - // We don't have to traverse to the children of the list since - // the list will propagate the change when it rerenders. - scheduleWorkOnFiber(node, renderLanes); - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } + case HostComponent: + pushHostContext(workInProgress); + break; - if (node === workInProgress) { - return; - } + case ClassComponent: { + var Component = workInProgress.type; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); + } + + break; + } + + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; + + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + pushProvider(workInProgress, context, newValue); + break; + } + + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + if (hasChildWork) { + workInProgress.flags |= Update; + } + } + + break; + + case SuspenseComponent: { + var state = workInProgress.memoizedState; + + if (state !== null) { + // whether to retry the primary children, or to skip over it and + // go straight to the fallback. Check the priority of the primary + // child fragment. - node = node.return; - } + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; - node.sibling.return = node.return; - node = node.sibling; - } -} + if (includesSomeLane(renderLanes, primaryChildLanes)) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + } else { + // The primary child fragment does not have pending work marked + // on it + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. -function 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; + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + // Note: We can return `null` here because we already checked + // whether there were nested context consumers, via the call to + // `bailoutOnAlreadyFinishedWork` above. + return null; + } + } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); + } - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; - } + break; + } - row = row.sibling; - } + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; - return lastContentRow; -} + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); -function validateRevealOrder(revealOrder) { - { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; + if (didSuspendBefore) { + if (_hasChildWork) { + // If something was in fallback state last time, and we have all the + // same children then we're still in progressive loading state. + // Something might get unblocked by state updates or retries in the + // tree which will affect the tail. So we need to use the normal + // path to compute the correct tail. + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. - if (typeof revealOrder === "string") { - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'Use lowercase "%s" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + workInProgress.flags |= DidCapture; + } // If nothing suspended before and we're rendering the same children, + // then the tail doesn't matter. Anything new that suspends will work + // in the "together" mode, so we can continue from the state we had. - break; + var renderState = workInProgress.memoizedState; + + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + renderState.lastEffect = null; } - case "forward": - case "backward": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'React uses the -s suffix in the spelling. Use "%ss" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (_hasChildWork) { break; + } else { + // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + return null; } + } - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - - break; + case OffscreenComponent: + case LegacyHiddenComponent: { + // Need to check if the tree still needs to be deferred. This is + // almost identical to the logic used in the normal update path, + // so we'll just enter that. The only difference is we'll bail out + // at the next level instead of this one, because the child props + // have not changed. Which is fine. + // TODO: Probably should refactor `beginWork` to split the bailout + // path from the normal path. I'm tempted to do a labeled break here + // but I won't :) + workInProgress.lanes = NoLanes; + return updateOffscreenComponent(current, workInProgress, renderLanes); } - } else { - error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); } - } - } -} - -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; - - error( - '"%s" is not a supported value for tail on . ' + - 'Did you mean "collapsed" or "hidden"?', - tailMode - ); - } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { - didWarnAboutTailOptions[tailMode] = true; - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode - ); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } else { + if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + } else { + // An update was scheduled on this fiber, but there are no new props + // nor legacy context. Set this to false. If an update queue or context + // consumer produces a changed value, it will set this to true. Otherwise, + // the component will assume the children have not changed and bail out. + didReceiveUpdate = false; } } - } -} + } else { + didReceiveUpdate = false; + } // Before entering the begin phase, clear pending update priority. + // TODO: This assumes that we're about to evaluate the component and process + // the update queue. However, there's an exception: SimpleMemoComponent + // sometimes bails out later in the begin phase. This indicates that we should + // move this assignment out of the common path and into each branch. -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + workInProgress.lanes = NoLanes; - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateLanes, + renderLanes ); + } - return false; + case FunctionComponent: { + var _Component = workInProgress.type; + var unresolvedProps = workInProgress.pendingProps; + var resolvedProps = + workInProgress.elementType === _Component + ? unresolvedProps + : resolveDefaultProps(_Component, unresolvedProps); + return updateFunctionComponent( + current, + workInProgress, + _Component, + resolvedProps, + renderLanes + ); } - } - return true; -} + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; -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); + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderLanes + ); + } - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + case HostComponent: + return updateHostComponent(current, workInProgress, renderLanes); - _i++; - } - } - } else { - error( - 'A single row was passed to a . ' + - "This is not useful since it needs multiple rows. " + - "Did you mean to pass multiple children or an array?", - revealOrder - ); - } - } - } - } -} + case HostText: + return updateHostText(); -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - var renderState = workInProgress.memoizedState; + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering - }; - } else { - // We can reuse the existing object from previous renders. - renderState.isBackwards = isBackwards; - renderState.rendering = null; - renderState.renderingStartTime = 0; - renderState.last = lastContentRow; - renderState.tail = tail; - renderState.tailMode = tailMode; - renderState.lastEffect = lastEffectBeforeRendering; - } -} // This can end up rendering this component multiple passes. -// The first pass splits the children fibers into two sets. A head and tail. -// We first render the head. If anything is in fallback state, we do another -// pass through beginWork to rerender all children (including the tail) with -// the force suspend context. If the first render didn't have anything in -// in fallback state. Then we render each row in the tail one-by-one. -// That happens in the completeWork phase without going back to beginWork. + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); -function updateSuspenseListComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var revealOrder = nextProps.revealOrder; - var tailMode = nextProps.tail; - var newChildren = nextProps.children; - validateRevealOrder(revealOrder); - validateTailOptions(tailMode, revealOrder); - validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren(current, workInProgress, newChildren, renderLanes); - var suspenseContext = suspenseStackCursor.current; - var shouldForceFallback = hasSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - if (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.flags |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.flags & DidCapture) !== NoFlags; + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); - 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( + return updateForwardRef( + current, workInProgress, - workInProgress.child, + type, + _resolvedProps2, renderLanes ); } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - pushSuspenseContext(workInProgress, suspenseContext); + case Mode: + return updateMode(current, workInProgress, renderLanes); - if ((workInProgress.mode & BlockingMode) === NoMode) { - // In legacy mode, SuspenseList doesn't work so we just - // use make it a noop by treating it as the default revealOrder. - workInProgress.memoizedState = null; - } else { - switch (revealOrder) { - case "forwards": { - var lastContentRow = findLastContentRow(workInProgress.child); - var tail; + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - 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; - } + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode, - workInProgress.lastEffect - ); - break; - } + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); - case "backwards": { - // We're going to find the first row that has existing content. - // At the same time we're going to reverse the list of everything - // we pass in the meantime. That's going to be our tail in reverse - // order. - var _tail = null; - var row = workInProgress.child; - workInProgress.child = null; + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentNameFromType(_type2) + ); } + } + } - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateLanes, + renderLanes + ); + } - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect - ); - break; - } + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateLanes, + renderLanes + ); + } - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect - ); - break; - } + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; + + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); + + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderLanes + ); + } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; - } + case SuspenseListComponent: { + return updateSuspenseListComponent(current, workInProgress, renderLanes); } - } - return workInProgress.child; -} + case ScopeComponent: { + break; + } -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; + case OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); + } - if (current === null) { - // Portals are special because we don't append the children during mount - // but at commit. Therefore we need to track insertions which the normal - // flow doesn't do during mount. This doesn't happen at the root because - // the root always starts with a "current" with a null child. - // TODO: Consider unifying this with how the root works. - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes + case LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + } + } + + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); } +} - return workInProgress.child; +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; } -var hasWarnedAboutUsingNoValuePropOnContextProvider = false; +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; +} -function updateContextProvider(current, workInProgress, renderLanes) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; +{ + // Mutation mode + appendAllChildren = function( + parent, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; - error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - ); + while (node !== null) { + if (node.tag === HostComponent || node.tag === HostText) { + appendInitialChild(parent, node.stateNode); + } else if (node.tag === HostPortal); + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - } - var providerPropTypes = workInProgress.type.propTypes; + if (node === workInProgress) { + return; + } - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; } - } + }; - pushProvider(workInProgress, newValue); + updateHostContainer = function(current, workInProgress) { + // Noop + }; - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + // If we have an alternate, that means this is an update and we need to + // schedule a side-effect to do the updates. + var oldProps = current.memoizedProps; - if (changedBits === 0) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange(workInProgress, context, changedBits, renderLanes); + if (oldProps === newProps) { + // In mutation mode, this is sufficient for a bailout because + // we won't touch this node even if children changed. + return; + } // If we get updated because one of our children updated, we don't + // have newProps so we'll have to reuse them. + // TODO: Split the update API as separate for the props vs. children. + // Even better would be if children weren't special cased at all tho. + + var instance = workInProgress.stateNode; + var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host + // component is hitting the resume path. Figure out why. Possibly + // related to `hidden`. + + var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + + workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there + // is a new ref we mark this as an update. All the work is done in commitWork. + + if (updatePayload) { + markUpdate(workInProgress); } - } + }; - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; + updateHostText$1 = function(current, workInProgress, oldText, newText) { + // If the text differs, mark it as an update. All the work in done in commitWork. + if (oldText !== newText) { + markUpdate(workInProgress); + } + }; } -var hasWarnedAboutUsingContextAsConsumer = false; +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; -function updateContextConsumer(current, workInProgress, renderLanes) { - var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In - // DEV mode, we create a separate object for Context.Consumer that acts - // like a proxy to Context. This proxy object adds unnecessary code in PROD - // so we use the old behaviour (Context.Consumer references Context) to - // reduce size and overhead. The separate object references context via - // a property called "_context", which also gives us the ability to check - // in DEV mode if this property exists or not and warn if it does not. + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - { - if (context._context === undefined) { - // This may be because it's a Context (rather than a Consumer). - // Or it may be because it's older React where they're the same thing. - // We only want to warn if we're sure it's a new React. - if (context !== context.Consumer) { - if (!hasWarnedAboutUsingContextAsConsumer) { - hasWarnedAboutUsingContextAsConsumer = true; + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); - } + 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; } - } else { - context = context._context; + + break; } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; - { - if (typeof render !== "function") { - error( - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ); + while (_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; } } +} - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. + if (!didBailout) { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var actualDuration = completedWork.actualDuration; + var treeBaseDuration = completedWork.selfBaseDuration; + var child = completedWork.child; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes) + ); + subtreeFlags |= child.subtreeFlags; + subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will + // only be updated if work is done on the fiber (i.e. it doesn't bailout). + // When work is done, it should bubble to the parent's actualDuration. If + // the fiber has not been cloned though, (meaning no work was done), then + // this value will reflect the amount of time spent working on a previous + // render. In that case it should not bubble. We determine whether it was + // cloned by comparing the child pointer. -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; - } + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; - { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); - } + while (_child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child.lanes, _child.childLanes) + ); + subtreeFlags |= _child.subtreeFlags; + subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. - markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. + _child.return = completedWork; + _child = _child.sibling; + } + } - if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { - // The children don't have any work either. We can skip them. - // TODO: Once we add back resuming, we should check if the children are - // a work-in-progress set. If so, we need to transfer their effects. - return null; + completedWork.subtreeFlags |= subtreeFlags; } else { - // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - cloneChildFibers(current, workInProgress); - return workInProgress.child; - } -} + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var _treeBaseDuration = completedWork.selfBaseDuration; + var _child2 = completedWork.child; + + while (_child2 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child2.lanes, _child2.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; + while (_child3 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child3.lanes, _child3.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + completedWork.subtreeFlags |= subtreeFlags; + } - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + completedWork.childLanes = newChildLanes; + return didBailout; +} - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); - } +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); - } + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + popContext(workInProgress); } - prevSibling.sibling = newWorkInProgress; - } // Delete the old fiber and place the new one. - // Since the old fiber is disconnected, we have to schedule it manually. + bubbleProperties(workInProgress); + return null; + } - var last = returnFiber.lastEffect; + case HostRoot: { + var fiberRoot = workInProgress.stateNode; - if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; - } + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); - current.nextEffect = null; - current.flags = Deletion; - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } - return newWorkInProgress; - } -} + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } else if (!fiberRoot.hydrate) { + // Schedule an effect to clear this container at the start of the next commit. + // This handles the case of React rendering into a container with previous children. + // It's also safe to do for updates too, because current.child would only be null + // if the previous render was null (so the the container would already be empty). + workInProgress.flags |= Snapshot; + } + } - { - if (workInProgress._debugNeedsRemount && current !== null) { - // This will restart the begin phase with a new fiber. - return remountFiber( - current, - workInProgress, - createFiberFromTypeAndProps( - workInProgress.type, - workInProgress.key, - workInProgress.pendingProps, - workInProgress._debugOwner || null, - workInProgress.mode, - workInProgress.lanes - ) - ); + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + return null; } - } - - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; - if ( - oldProps !== newProps || - hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: - workInProgress.type !== current.type - ) { - // If props or context changed, mark the fiber as having performed work. - // This may be unset if the props are determined to be equal later (memo). - didReceiveUpdate = true; - } else if (!includesSomeLane(renderLanes, updateLanes)) { - didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering - // the begin phase. There's still some bookkeeping we that needs to be done - // in this optimized path, mostly pushing stuff onto the stack. + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); - case HostComponent: - pushHostContext(workInProgress); - break; + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } + } else { + if (!newProps) { + if (!(workInProgress.stateNode !== null)) { + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. - case ClassComponent: { - var Component = workInProgress.type; + bubbleProperties(workInProgress); + return null; + } - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context + // "stack" as the parent. Then append children as we go in beginWork + // or completeWork depending on whether we want to add them top->down or + // bottom->up. Top->down is faster in IE11. - break; - } + var _wasHydrated = popHydrationState(); - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo + if (_wasHydrated) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + if (prepareToHydrateHostInstance()) { + // If changes to the hydrated node need to be applied at the + // commit-phase we mark this as such. + markUpdate(workInProgress); + } + } else { + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress ); - break; + appendAllChildren(instance, workInProgress, false, false); + workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. + // (eg DOM renderer supports auto-focus for certain elements). + // Make sure such renderers get scheduled for later work. - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; + if (finalizeInitialChildren(instance)) { + markUpdate(workInProgress); + } } - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); - - if (hasChildWork) { - workInProgress.flags |= Update; - } // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } + bubbleProperties(workInProgress); + return null; + } - break; + case HostText: { + var newText = newProps; - case SuspenseComponent: { - var state = workInProgress.memoizedState; + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. - if (state !== null) { - // whether to retry the primary children, or to skip over it and - // go straight to the fallback. Check the priority of the primary - // child fragment. + updateHostText$1(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (!(workInProgress.stateNode !== null)) { + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + } - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; + var _rootContainerInstance = getRootHostContainer(); - if (includesSomeLane(renderLanes, primaryChildLanes)) { - // The primary children have pending work. Use the normal path - // to attempt to render the primary children again. - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - } else { - // The primary child fragment does not have pending work marked - // on it - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); // The primary children do not have pending work with sufficient - // priority. Bailout. + var _currentHostContext = getHostContext(); - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + var _wasHydrated2 = popHydrationState(); - if (child !== null) { - // The fallback children have pending work. Skip over the - // primary children and work on the fallback. - return child.sibling; - } else { - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); } - - break; + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); } + } - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + bubbleProperties(workInProgress); + return null; + } - var _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - if (didSuspendBefore) { - if (_hasChildWork) { - // If something was in fallback state last time, and we have all the - // same children then we're still in progressive loading state. - // Something might get unblocked by state updates or retries in the - // tree which will affect the tail. So we need to use the normal - // path to compute the correct tail. - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - } // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - workInProgress.flags |= DidCapture; - } // If nothing suspended before and we're rendering the same children, - // then the tail doesn't matter. Anything new that suspends will work - // in the "together" mode, so we can continue from the state we had. + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. - var renderState = workInProgress.memoizedState; + return workInProgress; + } - if (renderState !== null) { - // Reset to the "together" mode in case we've started a different - // update in the past but didn't complete it. - renderState.rendering = null; - renderState.tail = null; - renderState.lastEffect = null; - } + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; + } - if (_hasChildWork) { - break; + if (nextDidTimeout && !prevDidTimeout) { + // TODO: This will still suspend a synchronous tree if anything + // in the concurrent tree already suspended during this render. + // This is a known bug. + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // TODO: Move this back to throwException because this is too late + // if this is a large tree which is common for initial loads. We + // don't know if we should restart a render or not until we get + // this marker, and this is too late. + // If this render already had a ping or lower pri updates, + // and this is the first time we know we're going to suspend we + // should be able to immediately restart from within throwException. + var hasInvisibleChildContext = + current === null && + workInProgress.memoizedProps.unstable_avoidThisFallback !== true; + + 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 { - // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. - return null; + // Otherwise, we're going to have to hide content so we should + // suspend for longer if possible. + renderDidSuspendDelayIfPossible(); } } + } - case OffscreenComponent: - case LegacyHiddenComponent: { - // Need to check if the tree still needs to be deferred. This is - // almost identical to the logic used in the normal update path, - // so we'll just enter that. The only difference is we'll bail out - // at the next level instead of this one, because the child props - // have not changed. Which is fine. - // TODO: Probably should refactor `beginWork` to split the bailout - // path from the normal path. I'm tempted to do a labeled break here - // but I won't :) - workInProgress.lanes = NoLanes; - return updateOffscreenComponent(current, workInProgress, renderLanes); + { + // TODO: Only schedule updates if these values are non equal, i.e. it changed. + if (nextDidTimeout || prevDidTimeout) { + // If this boundary just timed out, schedule an effect to attach a + // retry listener to the promise. This flag is also used to hide the + // primary children. In mutation mode, we also need the flag to + // *unhide* children that were previously hidden, so check if this + // is currently timed out, too. + workInProgress.flags |= Update; } } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } else { - if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } else { - // An update was scheduled on this fiber, but there are no new props - // nor legacy context. Set this to false. If an update queue or context - // consumer produces a changed value, it will set this to true. Otherwise, - // the component will assume the children have not changed and bail out. - didReceiveUpdate = false; + bubbleProperties(workInProgress); + + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment2 = workInProgress.child; + + if (_primaryChildFragment2 !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment2.treeBaseDuration; + } + } + } } + + return null; } - } else { - didReceiveUpdate = false; - } // Before entering the begin phase, clear pending update priority. - // TODO: This assumes that we're about to evaluate the component and process - // the update queue. However, there's an exception: SimpleMemoComponent - // sometimes bails out later in the begin phase. This indicates that we should - // move this assignment out of the common path and into each branch. - workInProgress.lanes = NoLanes; + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderLanes - ); - } + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateLanes, - renderLanes - ); - } + bubbleProperties(workInProgress); + return null; - case FunctionComponent: { - var _Component = workInProgress.type; - var unresolvedProps = workInProgress.pendingProps; - var resolvedProps = - workInProgress.elementType === _Component - ? unresolvedProps - : resolveDefaultProps(_Component, unresolvedProps); - return updateFunctionComponent( - current, - workInProgress, - _Component, - resolvedProps, - renderLanes - ); + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; + + case IncompleteClassComponent: { + // Same as class component case. I put it down here so that the tags are + // sequential to ensure this switch is compiled to a jump table. + var _Component = workInProgress.type; + + if (isContextProvider(_Component)) { + popContext(workInProgress); + } + + bubbleProperties(workInProgress); + return null; } - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderLanes - ); - } + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.flags & DidCapture) === NoFlags); - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); + if (!cannotBeSuspended) { + var row = workInProgress.child; - case HostText: - return updateHostText(); + while (row !== null) { + var suspended = findFirstSuspended(row); - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.flags |= DidCapture; + cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as + // part of the second pass. In that case nothing will subscribe to + // its thennables. Instead, we'll transfer its thennables to the + // SuspenseList so that it can retry if they resolve. + // There might be multiple of these in the list but since we're + // going to wait for all of them anyway, it doesn't really matter + // which ones gets to ping. In theory we could get clever and keep + // track of how many dependencies remain but it gets tricky because + // in the meantime, we can add/remove/change items and dependencies. + // We might bail out of the loop before finding any but that + // doesn't matter since that means that the other boundaries that + // we did find already has their listeners attached. - case HostPortal: - return updatePortalComponent(current, workInProgress, renderLanes); + var newThennables = suspended.updateQueue; - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.flags |= Update; + } // Rerender the whole list, but this time, we'll force fallbacks + // to stay in place. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - return updateForwardRef( - current, - workInProgress, - type, - _resolvedProps2, - renderLanes - ); - } + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. - case Fragment: - return updateFragment(current, workInProgress, renderLanes); + return workInProgress.child; + } - case Mode: - return updateMode(current, workInProgress, renderLanes); + row = row.sibling; + } + } - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); + if (renderState.tail !== null && now() > getRenderTargetTime()) { + // We have already passed our CPU deadline but we still have rows + // left in the tail. We'll just give up further attempts to render + // the main content and only render fallbacks. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); + workInProgress.lanes = SomeRetryLane; + } + } else { + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); + if (_suspended !== null) { + workInProgress.flags |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + var _newThennables = _suspended.updateQueue; - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.flags |= Update; + } - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + cutOffTailIfNeeded(renderState, true); // This might have been modified. - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We're done. + bubbleProperties(workInProgress); + return null; + } + } else if ( + // The time it took to render last row is greater than the remaining + // time we have to render. So rendering one more row would likely + // exceed it. + now() * 2 - renderState.renderingStartTime > + getRenderTargetTime() && + renderLanes !== OffscreenLane + ) { + // We have now passed our CPU deadline and we'll just give up further + // attempts to render the main content and only render fallbacks. + // The assumption is that this is usually faster. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + + workInProgress.lanes = SomeRetryLane; } } - } - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateLanes, - renderLanes - ); - } + 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; - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateLanes, - renderLanes - ); - } + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + renderState.last = renderedTail; + } + } - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + if (renderState.tail !== null) { + // We still have tail rows to render. + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.renderingStartTime = now(); + next.sibling = null; // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + + var suspenseContext = suspenseStackCursor.current; - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderLanes - ); - } + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); - } + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. - case FundamentalComponent: { - break; + return next; + } + + bubbleProperties(workInProgress); + return null; } case ScopeComponent: { break; } - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); - } - + case OffscreenComponent: case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; + + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" + ) { + workInProgress.flags |= Update; + } + } // Don't bubble properties for hidden children. + + if ( + !nextIsHidden || + includesSomeLane(subtreeRenderLanes, OffscreenLane) || + (workInProgress.mode & ConcurrentMode) === NoMode + ) { + bubbleProperties(workInProgress); + } + + return null; } } @@ -14881,2531 +15964,2445 @@ function beginWork(current, workInProgress, renderLanes) { } } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; -} - -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; -} - -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; - -{ - // Mutation mode - appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden - ) { - // We only have the top Fiber that was created but we need recurse down its - // children to find all the terminal nodes. - var node = workInProgress.child; +function unwindWork(workInProgress, renderLanes) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; - while (node !== null) { - if (node.tag === HostComponent || node.tag === HostText) { - appendInitialChild(parent, node.stateNode); - } else if (node.tag === HostPortal); - else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; + if (isContextProvider(Component)) { + popContext(workInProgress); } - if (node === workInProgress) { - return; - } + var flags = workInProgress.flags; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); } - node = node.return; + return workInProgress; } - node.sibling.return = node.return; - node = node.sibling; + return null; } - }; - - updateHostContainer = function(workInProgress) { - // Noop - }; - - updateHostComponent$1 = function( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ) { - // If we have an alternate, that means this is an update and we need to - // schedule a side-effect to do the updates. - var oldProps = current.memoizedProps; - - if (oldProps === newProps) { - // In mutation mode, this is sufficient for a bailout because - // we won't touch this node even if children changed. - return; - } // If we get updated because one of our children updated, we don't - // have newProps so we'll have to reuse them. - // TODO: Split the update API as separate for the props vs. children. - // Even better would be if children weren't special cased at all tho. - - var instance = workInProgress.stateNode; - var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host - // component is hitting the resume path. Figure out why. Possibly - // related to `hidden`. - var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); + var _flags = workInProgress.flags; - workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there - // is a new ref we mark this as an update. All the work is done in commitWork. + if (!((_flags & DidCapture) === NoFlags)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + } - if (updatePayload) { - markUpdate(workInProgress); + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; } - }; - updateHostText$1 = function(current, workInProgress, oldText, newText) { - // If the text differs, mark it as an update. All the work in done in commitWork. - if (oldText !== newText) { - markUpdate(workInProgress); + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; } - }; -} -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; + case SuspenseComponent: { + popSuspenseContext(workInProgress); - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; - } + var _flags2 = workInProgress.flags; - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. - if (lastTailNode === null) { - // All remaining items in the tail are insertions. - renderState.tail = null; - } else { - // Detach the insertion after the last node that was already - // inserted. - lastTailNode.sibling = null; + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; } - break; + return null; } - case "collapsed": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var _tailNode = renderState.tail; - var _lastTailNode = null; - - 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; - } + 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. - break; + return null; } - } -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; + case HostPortal: + popHostContainer(workInProgress); + return null; - switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: + case ContextProvider: + var context = workInProgress.type._context; + popProvider(context, workInProgress); return null; - case ClassComponent: { - var Component = workInProgress.type; - - if (isContextProvider(Component)) { - popContext(workInProgress); - } + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); return null; - } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - var fiberRoot = workInProgress.stateNode; + case CacheComponent: + return null; - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } + default: + return null; + } +} - if (current === null || current.child === null) { - // If we hydrated, pop so that we can delete any remaining children - // that weren't hydrated. - var wasHydrated = popHydrationState(); +function unwindInterruptedWork(interruptedWork, renderLanes) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); - } else if (!fiberRoot.hydrate) { - // Schedule an effect to clear this container at the start of the next commit. - // This handles the case of React rendering into a container with previous children. - // It's also safe to do for updates too, because current.child would only be null - // if the previous render was null (so the the container would already be empty). - workInProgress.flags |= Snapshot; - } + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); } - updateHostContainer(workInProgress); - return null; + break; + } + + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + resetWorkInProgressVersions(); + break; } case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + popHostContext(interruptedWork); + break; + } - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + case HostPortal: + popHostContainer(interruptedWork); + break; - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } - } else { - if (!newProps) { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - return null; - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context - // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on whether we want to add them top->down or - // bottom->up. Top->down is faster in IE11. + case ContextProvider: + var context = interruptedWork.type._context; + popProvider(context, interruptedWork); + break; - var _wasHydrated = popHydrationState(); + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(interruptedWork); - if (_wasHydrated) { - // TODO: Move this and createInstance step into the beginPhase - // to consolidate. - if (prepareToHydrateHostInstance()) { - // If changes to the hydrated node need to be applied at the - // commit-phase we mark this as such. - markUpdate(workInProgress); - } - } else { - var instance = createInstance( - type, - newProps, - rootContainerInstance, - currentHostContext, - workInProgress - ); - appendAllChildren(instance, workInProgress, false, false); - workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. - // (eg DOM renderer supports auto-focus for certain elements). - // Make sure such renderers get scheduled for later work. + break; + } +} - if (finalizeInitialChildren(instance)) { - markUpdate(workInProgress); - } - } +function createCapturedValue(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - return null; - } +function showErrorDialog(boundary, errorInfo) { + var capturedError = { + componentStack: errorInfo.stack !== null ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + boundary !== null && boundary.tag === ClassComponent + ? boundary.stateNode + : null + }; + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - case HostText: { - var newText = newProps; +function logCapturedError(boundary, errorInfo) { + try { + var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - if (current && workInProgress.stateNode != null) { - var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need - // to schedule a side-effect to do the updates. + if (logError === false) { + return; + } - updateHostText$1(current, workInProgress, oldText, newText); - } else { - if (typeof newText !== "string") { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. - } + var error = errorInfo.value; - var _rootContainerInstance = getRootHostContainer(); + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - var _currentHostContext = getHostContext(); + if (error != null && error._suppressLogging) { + if (boundary.tag === ClassComponent) { + // The error is recoverable and was silenced. + // Ignore it and don't print the stack addendum. + // This is handy for testing error boundaries without noise. + return; + } // The error is fatal. Since the silencing might have + // been accidental, we'll surface it anyway. + // However, the browser would have silenced the original error + // so we'll print it first, and then print the stack addendum. - var _wasHydrated2 = popHydrationState(); + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 + } - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } + var componentName = source ? getComponentNameFromFiber(source) : null; + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; + + if (boundary.tag === HostRoot) { + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + } else { + var errorBoundaryName = + getComponentNameFromFiber(boundary) || "Anonymous"; + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); } - return null; - } + var combinedMessage = + componentNameMessage + + "\n" + + componentStack + + "\n\n" + + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. + // We don't include the original error message and JS stack because the browser + // has already printed it. Even if the application swallows the error, it is still + // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + console["error"](combinedMessage); // Don't transform to our wrapper + } else { + // In production, we print the error directly. + // This will include the message, the JS stack, and anything the browser wants to show. + // We pass the error object instead of custom message so that the browser displays the error natively. + console["error"](error); // Don't transform to our wrapper + } + } catch (e) { + // This method must not throw, or React internal state will get messed up. + // If console.error is overridden, or logCapturedError() shows a dialog that throws, + // we want to report this error outside of the normal stack as a last resort. + // https://github.com/facebook/react/issues/13188 + setTimeout(function() { + throw e; + }); + } +} - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. +var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } +function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. - return workInProgress; - } + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + update.payload = { + element: null + }; + var error = errorInfo.value; - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); - } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; - } + update.callback = function() { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; - if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in blocking mode we can suspend, - // otherwise we won't suspend. - // TODO: This will still suspend a synchronous tree if anything - // in the concurrent tree already suspended during this render. - // This is a known bug. - if ((workInProgress.mode & BlockingMode) !== NoMode) { - // TODO: Move this back to throwException because this is too late - // if this is a large tree which is common for initial loads. We - // don't know if we should restart a render or not until we get - // this marker, and this is too late. - // If this render already had a ping or lower pri updates, - // and this is the first time we know we're going to suspend we - // should be able to immediately restart from within throwException. - var hasInvisibleChildContext = - current === null && - workInProgress.memoizedProps.unstable_avoidThisFallback !== true; + return update; +} - 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(); - } - } - } +function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - { - // TODO: Only schedule updates if these values are non equal, i.e. it changed. - if (nextDidTimeout || prevDidTimeout) { - // If this boundary just timed out, schedule an effect to attach a - // retry listener to the promise. This flag is also used to hide the - // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if this - // is currently timed out, too. - workInProgress.flags |= Update; - } - } + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; - return null; - } + update.payload = function() { + logCapturedError(fiber, errorInfo); + return getDerivedStateFromError(error$1); + }; + } - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); + var inst = fiber.stateNode; - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); + if (inst !== null && typeof inst.componentDidCatch === "function") { + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); } - return null; - - case ContextProvider: - // Pop provider fiber - popProvider(workInProgress); - return null; - - case IncompleteClassComponent: { - // Same as class component case. I put it down here so that the tags are - // sequential to ensure this switch is compiled to a jump table. - var _Component = workInProgress.type; + if (typeof getDerivedStateFromError !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromError is + // not defined. + markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined - if (isContextProvider(_Component)) { - popContext(workInProgress); + logCapturedError(fiber, errorInfo); } - return null; - } - - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - return null; + { + if (typeof getDerivedStateFromError !== "function") { + // If componentDidCatch is the only error boundary method defined, + // then it needs to call setState to recover from errors. + // If no state update is scheduled then the boundary will swallow the error. + if (!includesSomeLane(fiber.lanes, SyncLane)) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentNameFromFiber(fiber) || "Unknown" + ); + } + } } + }; + } else { + update.callback = function() { + markFailedErrorBoundaryForHotReloading(fiber); + }; + } - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; + return update; +} - if (renderedTail === null) { - // We just rendered the head. - if (!didSuspendAlready) { - // This is the first pass. We need to figure out if anything is still - // suspended in the rendered set. - // If new content unsuspended, but there's still some content that - // didn't. Then we need to do a second pass that forces everything - // to keep showing their fallbacks. - // We might be suspended if something in this render pass suspended, or - // something in the previous committed pass suspended. Otherwise, - // there's no chance so we can skip the expensive call to - // findFirstSuspended. - var cannotBeSuspended = - renderHasNotSuspendedYet() && - (current === null || (current.flags & DidCapture) === NoFlags); +function attachPingListener(root, wakeable, lanes) { + // Attach a listener to the promise to "ping" the root and retry. But only if + // one does not already exist for the lanes we're currently rendering (which + // acts like a "thread ID" here). + var pingCache = root.pingCache; + var threadIDs; - if (!cannotBeSuspended) { - var row = workInProgress.child; + if (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap$1(); + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } else { + threadIDs = pingCache.get(wakeable); - while (row !== null) { - var suspended = findFirstSuspended(row); + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } - if (suspended !== null) { - didSuspendAlready = true; - workInProgress.flags |= DidCapture; - cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as - // part of the second pass. In that case nothing will subscribe to - // its thennables. Instead, we'll transfer its thennables to the - // SuspenseList so that it can retry if they resolve. - // There might be multiple of these in the list but since we're - // going to wait for all of them anyway, it doesn't really matter - // which ones gets to ping. In theory we could get clever and keep - // track of how many dependencies remain but it gets tricky because - // in the meantime, we can add/remove/change items and dependencies. - // We might bail out of the loop before finding any but that - // doesn't matter since that means that the other boundaries that - // we did find already has their listeners attached. + if (!threadIDs.has(lanes)) { + // Memoize using the thread ID to prevent redundant listeners. + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); - var newThennables = suspended.updateQueue; + wakeable.then(ping, ping); + } +} - if (newThennables !== null) { - workInProgress.updateQueue = newThennables; - workInProgress.flags |= Update; - } // Rerender the whole list, but this time, we'll force fallbacks - // to stay in place. - // Reset the effect list before doing the second pass since that's now invalid. +function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes +) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } + if ( + value !== null && + typeof value === "object" && + typeof value.then === "function" + ) { + var wakeable = value; + // A legacy mode Suspense quirk, only relevant to hook components. - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + var tag = sourceFiber.tag; - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + if ( + (sourceFiber.mode & ConcurrentMode) === NoMode && + (tag === FunctionComponent || + tag === ForwardRef || + tag === SimpleMemoComponent) + ) { + var currentSource = sourceFiber.alternate; - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; + } + } - row = row.sibling; - } - } + var hasInvisibleParentBoundary = hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ); // Schedule the nearest Suspense to re-render the timed out view. - if (renderState.tail !== null && now() > getRenderTargetTime()) { - // We have already passed our CPU deadline but we still have rows - // left in the tail. We'll just give up further attempts to render - // the main content and only render fallbacks. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. + var _workInProgress = returnFiber; - workInProgress.lanes = SomeRetryLane; + do { + if ( + _workInProgress.tag === SuspenseComponent && + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) + ) { + // Found the nearest boundary. + // Stash the promise on the boundary fiber. If the boundary times out, we'll + // attach another listener to flip the boundary back to its normal state. + var wakeables = _workInProgress.updateQueue; - { - markSpawnedWork(SomeRetryLane); - } - } + if (wakeables === null) { + var updateQueue = new Set(); + updateQueue.add(wakeable); + _workInProgress.updateQueue = updateQueue; } else { - cutOffTailIfNeeded(renderState, false); - } // Next we're going to render the tail. - } else { - // Append the rendered row to the child list. - if (!didSuspendAlready) { - var _suspended = findFirstSuspended(renderedTail); + wakeables.add(wakeable); + } // If the boundary is in legacy 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 + // should *not* suspend the commit. + // + // If the suspense boundary suspended itself suspended, we don't have to + // do this trick because nothing was partially started. We can just + // directly do a second pass over the fallback in this render and + // pretend we meant to render that directly. - if (_suspended !== null) { - workInProgress.flags |= DidCapture; - didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't - // get lost if this row ends up dropped during a second pass. + if ( + (_workInProgress.mode & ConcurrentMode) === NoMode && + _workInProgress !== returnFiber + ) { + _workInProgress.flags |= DidCapture; + sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. + // But we shouldn't call any lifecycle methods or callbacks. Remove + // all lifecycle effect tags. - var _newThennables = _suspended.updateQueue; + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; + if (sourceFiber.tag === ClassComponent) { + var _currentSourceFiber = sourceFiber.alternate; + + if (_currentSourceFiber === null) { + // This is a new mount. Change the tag so it's not mistaken for a + // completed class component. For example, we should not call + // componentWillUnmount if it is deleted. + sourceFiber.tag = IncompleteClassComponent; + } else { + // When we try rendering again, we should not reuse the current fiber, + // since it's known to be in an inconsistent state. Use a force update to + // prevent a bail out. + var update = createUpdate(NoTimestamp, SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update); } + } // The source fiber did not complete. Mark it with Sync priority to + // indicate that it still has pending work. - cutOffTailIfNeeded(renderState, true); // This might have been modified. + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We need to delete the row we just rendered. - // Reset the effect list to what it was before we rendered this - // child. The nested children have already appended themselves. - var lastEffect = (workInProgress.lastEffect = - renderState.lastEffect); // Remove any effects that were appended after this point. + return; + } // Confirmed that the boundary is in a concurrent mode tree. Continue + // with the normal suspend path. + // + // After this we'll use a set of heuristics to determine whether this + // render pass will run to completion or restart or "suspend" the commit. + // The actual logic for this is spread out in different places. + // + // This first principle is that if we're going to suspend when we complete + // a root, then we should also restart if we get an update or ping that + // might unsuspend it, and vice versa. The only reason to suspend is + // because you think you might want to restart before committing. However, + // it doesn't make sense to restart only while in the period we're suspended. + // + // Restarting too aggressively is also not good because it starves out any + // intermediate loading state. So we use heuristics to determine when. + // Suspense Heuristics + // + // If nothing threw a Promise or all the same fallbacks are already showing, + // then don't suspend/restart. + // + // If this is an initial render of a new tree of Suspense boundaries and + // those trigger a fallback, then don't suspend/restart. We want to ensure + // that we can show the initial loading state as quickly as possible. + // + // If we hit a "Delayed" case, such as when we'd switch from content back into + // a fallback, then we should always suspend/restart. Transitions apply + // to this case. If none is defined, JND is used instead. + // + // If we're already showing a fallback and it gets "retried", allowing us to show + // another level, but there's still an inner boundary that would show a fallback, + // then we suspend/restart for 500ms since the last time we showed a fallback + // anywhere in the tree. This effectively throttles progressive loading into a + // consistent train of commits. This also gives us an opportunity to restart to + // get to the completed state slightly earlier. + // + // If there's ambiguity due to batching it's resolved in preference of: + // 1) "delayed", 2) "initial render", 3) "retry". + // + // We want to ensure that a "busy" state doesn't get force committed. We want to + // ensure that new initial loading states can commit as soon as possible. - if (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + attachPingListener(root, wakeable, rootRenderLanes); + _workInProgress.flags |= ShouldCapture; + _workInProgress.lanes = rootRenderLanes; + return; + } // This boundary already captured during this render. Continue to the next + // boundary. - return null; - } - } else if ( - // The time it took to render last row is greater than the remaining - // time we have to render. So rendering one more row would likely - // exceed it. - now() * 2 - renderState.renderingStartTime > - getRenderTargetTime() && - renderLanes !== OffscreenLane - ) { - // We have now passed our CPU deadline and we'll just give up further - // attempts to render the main content and only render fallbacks. - // The assumption is that this is usually faster. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. + _workInProgress = _workInProgress.return; + } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. + // TODO: Use invariant so the message is stripped in prod? - workInProgress.lanes = SomeRetryLane; + value = new Error( + (getComponentNameFromFiber(sourceFiber) || "A React component") + + " suspended while rendering, but no fallback UI was specified.\n" + + "\n" + + "Add a component higher in the tree to " + + "provide a loading indicator or placeholder to display." + ); + } // We didn't find a boundary that could handle this type of exception. Start + // over and traverse parent path again, this time treating the exception + // as an error. - { - markSpawnedWork(SomeRetryLane); - } - } - } + renderDidError(); + value = createCapturedValue(value, sourceFiber); + var workInProgress = returnFiber; - if (renderState.isBackwards) { - // The effect list of the backwards tail will have been added - // to the end. This breaks the guarantee that life-cycles fire in - // sibling order but that isn't a strong guarantee promised by React. - // Especially since these might also just pop in during future commits. - // Append to the beginning of the list. - renderedTail.sibling = workInProgress.child; - workInProgress.child = renderedTail; - } else { - var previousSibling = renderState.last; + do { + switch (workInProgress.tag) { + case HostRoot: { + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); - renderState.last = renderedTail; - } + enqueueCapturedUpdate(workInProgress, _update); + return; } - if (renderState.tail !== null) { - // We still have tail rows to render. - // Pop a row. - var next = renderState.tail; - renderState.rendering = next; - renderState.tail = next.sibling; - renderState.lastEffect = workInProgress.lastEffect; - renderState.renderingStartTime = now(); - next.sibling = null; // Restore the context. - // TODO: We can probably just avoid popping it instead and only - // setting it the first time we go from not suspended to suspended. + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; - var suspenseContext = suspenseStackCursor.current; + if ( + (workInProgress.flags & DidCapture) === NoFlags && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + var _lane = pickArbitraryLane(rootRenderLanes); - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state - return next; - } + var _update2 = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); - return null; - } + enqueueCapturedUpdate(workInProgress, _update2); + return; + } - case FundamentalComponent: { - break; + break; } - case ScopeComponent: { - break; - } + workInProgress = workInProgress.return; + } while (workInProgress !== null); +} - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - if (current !== null) { - var _nextState = workInProgress.memoizedState; - var _prevState = current.memoizedState; - var prevIsHidden = _prevState !== null; - var nextIsHidden = _nextState !== null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} // Used during the commit phase to track the state of the Offscreen component stack. +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +var nextEffect = null; // Used for Profiling builds to track updaters. - if ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" - ) { - workInProgress.flags |= Update; - } - } +var callComponentWillUnmountWithTimer = function(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; - return null; - } + { + instance.componentWillUnmount(); } +}; // Capture errors so they don't interrupt mounting. +function safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance +) { { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance ); - } -} - -function unwindWork(workInProgress, renderLanes) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; - - if (isContextProvider(Component)) { - popContext(workInProgress); - } - var flags = workInProgress.flags; + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, unmountError); + } + } +} // Capture errors so they don't interrupt mounting. - if (flags & ShouldCapture) { - workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; +function safelyDetachRef(current, nearestMountedAncestor) { + var ref = current.ref; - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); + if (ref !== null) { + if (typeof ref === "function") { + { + { + invokeGuardedCallback(null, ref, null, null); } - return workInProgress; + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, refError); + } } - - return null; + } else { + ref.current = null; } + } +} - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - var _flags = workInProgress.flags; - - if (!((_flags & DidCapture) === NoFlags)) { - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - - workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; - return workInProgress; - } +function safelyCallDestroy(current, nearestMountedAncestor, destroy) { + { + invokeGuardedCallback(null, destroy, null); - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, error); } + } +} - case SuspenseComponent: { - popSuspenseContext(workInProgress); +var focusedInstanceHandle = null; +var shouldFireAfterActiveInstanceBlur = false; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = prepareForCommit(root.containerInfo); + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber - var _flags2 = workInProgress.flags; + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + focusedInstanceHandle = null; + return shouldFire; +} - if (_flags2 & ShouldCapture) { - workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. +function commitBeforeMutationEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + var deletions = fiber.deletions; - return workInProgress; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var deletion = deletions[i]; + commitBeforeMutationEffectsDeletion(deletion); } - - return null; } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been - // caught by a nested boundary. If not, it should bubble through. + var child = fiber.child; - return null; + if ( + (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && + child !== null + ) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitBeforeMutationEffects_complete(); } - - case HostPortal: - popHostContainer(workInProgress); - return null; - - case ContextProvider: - popProvider(workInProgress); - return null; - - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(workInProgress); - return null; - - default: - return null; } } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; +function commitBeforeMutationEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitBeforeMutationEffectsOnFiber, + null, + fiber + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - break; + resetCurrentFiber(); } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - resetWorkInProgressVersions(); - break; - } + var sibling = fiber.sibling; - case HostComponent: { - popHostContext(interruptedWork); - break; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - case HostPortal: - popHostContainer(interruptedWork); - break; - - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; - - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; + nextEffect = fiber.return; + } +} - case ContextProvider: - popProvider(interruptedWork); - break; +function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(interruptedWork); - break; + if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { + // Check to see if the focused element was inside of a hidden (Suspense) subtree. + // TODO: Move this out of the hot path using a dedicated effect tag. + if ( + finishedWork.tag === SuspenseComponent && + isSuspenseBoundaryBeingHidden(current, finishedWork) && + doesFiberContain(finishedWork, focusedInstanceHandle) + ) { + shouldFireAfterActiveInstanceBlur = true; + } } -} -function createCapturedValue(value, source) { - // If the value is an error, call this function immediately after it is thrown - // so the stack is accurate. - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(finishedWork); -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + break; + } -function showErrorDialog(boundary, errorInfo) { - var capturedError = { - componentStack: errorInfo.stack !== null ? errorInfo.stack : "", - error: errorInfo.value, - errorBoundary: - boundary !== null && boundary.tag === ClassComponent - ? boundary.stateNode - : null - }; - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + case ClassComponent: { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + var instance = finishedWork.stateNode; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } -function logCapturedError(boundary, errorInfo) { - try { - var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + } + } - if (logError === false) { - return; - } + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - var error = errorInfo.value; + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - if (true) { - var source = errorInfo.source; - var stack = errorInfo.stack; - var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); - if (error != null && error._suppressLogging) { - if (boundary.tag === ClassComponent) { - // The error is recoverable and was silenced. - // Ignore it and don't print the stack addendum. - // This is handy for testing error boundaries without noise. - return; - } // The error is fatal. Since the silencing might have - // been accidental, we'll surface it anyway. - // However, the browser would have silenced the original error - // so we'll print it first, and then print the stack addendum. + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentNameFromFiber(finishedWork) + ); + } + } - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + + break; } - var componentName = source ? getComponentName(source.type) : null; - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; - var errorBoundaryName = getComponentName(boundary.type); + case HostRoot: { + { + var root = finishedWork.stateNode; + clearContainer(root.containerInfo); + } - if (errorBoundaryName) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); - } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + break; } - var combinedMessage = - componentNameMessage + - "\n" + - componentStack + - "\n\n" + - ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. - // We don't include the original error message and JS stack because the browser - // has already printed it. Even if the application swallows the error, it is still - // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + break; - console["error"](combinedMessage); // Don't transform to our wrapper - } else { - // In production, we print the error directly. - // This will include the message, the JS stack, and anything the browser wants to show. - // We pass the error object instead of custom message so that the browser displays the error natively. - console["error"](error); // Don't transform to our wrapper + default: { + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } } - } catch (e) { - // This method must not throw, or React internal state will get messed up. - // If console.error is overridden, or logCapturedError() shows a dialog that throws, - // we want to report this error outside of the normal stack as a last resort. - // https://github.com/facebook/react/issues/13188 - setTimeout(function() { - throw e; - }); + + resetCurrentFiber(); } } -var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; +function commitBeforeMutationEffectsDeletion(deletion) { + // TODO (effects) It would be nice to avoid calling doesFiberContain() + // Maybe we can repurpose one of the subtreeFlags positions for this instead? + // Use it to store which part of the tree the focused instance is in? + // This assumes we can safely determine that instance during the "render" phase. + if (doesFiberContain(deletion, focusedInstanceHandle)) { + shouldFireAfterActiveInstanceBlur = true; + } +} -function createRootErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor +) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property - // being called "element". + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - update.payload = { - element: null - }; - var error = errorInfo.value; + do { + if ((effect.tag & flags) === flags) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; - update.callback = function() { - onUncaughtError(error); - logCapturedError(fiber, errorInfo); - }; + if (destroy !== undefined) { + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + } + } - return update; + effect = effect.next; + } while (effect !== firstEffect); + } } -function createClassErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); - update.tag = CaptureUpdate; - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - - if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; - - update.payload = function() { - logCapturedError(fiber, errorInfo); - return getDerivedStateFromError(error$1); - }; - } +function commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - var inst = fiber.stateNode; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - { - markFailedErrorBoundaryForHotReloading(fiber); - } + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); - if (typeof getDerivedStateFromError !== "function") { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromError is - // not defined. - markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + { + var destroy = effect.destroy; - logCapturedError(fiber, errorInfo); - } + if (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; - var error$1 = errorInfo.value; - var stack = errorInfo.stack; - this.componentDidCatch(error$1, { - componentStack: stack !== null ? stack : "" - }); + if (destroy === null) { + addendum = + " You returned null. If your effect does not require clean " + + "up, return undefined (or nothing)."; + } else if (typeof destroy.then === "function") { + addendum = + "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + "useEffect(() => {\n" + + " async function fetchData() {\n" + + " // You can await here\n" + + " const response = await MyAPI.getData(someId);\n" + + " // ...\n" + + " }\n" + + " fetchData();\n" + + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } - { - if (typeof getDerivedStateFromError !== "function") { - // If componentDidCatch is the only error boundary method defined, - // then it needs to call setState to recover from errors. - // If no state update is scheduled then the boundary will swallow the error. - if (!includesSomeLane(fiber.lanes, SyncLane)) { error( - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s", + addendum ); } } } - }; - } else { - update.callback = function() { - markFailedErrorBoundaryForHotReloading(fiber); - }; - } - - return update; -} - -function attachPingListener(root, wakeable, lanes) { - // Attach a listener to the promise to "ping" the root and retry. But only if - // one does not already exist for the lanes we're currently rendering (which - // acts like a "thread ID" here). - var pingCache = root.pingCache; - var threadIDs; - - if (pingCache === null) { - pingCache = root.pingCache = new PossiblyWeakMap$1(); - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } else { - threadIDs = pingCache.get(wakeable); - - if (threadIDs === undefined) { - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } - } - - if (!threadIDs.has(lanes)) { - // Memoize using the thread ID to prevent redundant listeners. - threadIDs.add(lanes); - var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); - wakeable.then(ping, ping); + + effect = effect.next; + } while (effect !== firstEffect); } } -function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes +function commitLayoutEffectOnFiber( + finishedRoot, + current, + finishedWork, + committedLanes ) { - // The source fiber did not complete. - sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. + if ((finishedWork.flags & (Update | Callback)) !== NoFlags) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + break; + } - if ( - value !== null && - typeof value === "object" && - typeof value.then === "function" - ) { - // This is a wakeable. - var wakeable = value; + case ClassComponent: { + var instance = finishedWork.stateNode; - if ((sourceFiber.mode & BlockingMode) === NoMode) { - // Reset the memoizedState to what it was before we attempted - // to render it. - var currentSource = sourceFiber.alternate; + if (finishedWork.flags & Update) { + if (current === null) { + // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } - if (currentSource) { - sourceFiber.updateQueue = currentSource.updateQueue; - sourceFiber.memoizedState = currentSource.memoizedState; - sourceFiber.lanes = currentSource.lanes; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; - } - } + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + } + } - var hasInvisibleParentBoundary = hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ); // Schedule the nearest Suspense to re-render the timed out view. + { + instance.componentDidMount(); + } + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - var _workInProgress = returnFiber; + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } - do { - if ( - _workInProgress.tag === SuspenseComponent && - shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) - ) { - // Found the nearest boundary. - // Stash the promise on the boundary fiber. If the boundary times out, we'll - // attach another listener to flip the boundary back to its normal state. - var wakeables = _workInProgress.updateQueue; + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + } + } - if (wakeables === null) { - var updateQueue = new Set(); - updateQueue.add(wakeable); - _workInProgress.updateQueue = updateQueue; - } else { - wakeables.add(wakeable); - } // If the boundary is outside of blocking mode, we should *not* - // suspend the commit. Pretend as if the suspended component rendered - // null and keep rendering. In the commit phase, we'll schedule a - // subsequent synchronous update to re-render the Suspense. - // - // Note: It doesn't matter whether the component that suspended was - // inside a blocking mode tree. If the Suspense is outside of it, we - // should *not* suspend the commit. + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. - if ((_workInProgress.mode & BlockingMode) === NoMode) { - _workInProgress.flags |= DidCapture; - sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. - // But we shouldn't call any lifecycle methods or callbacks. Remove - // all lifecycle effect tags. + var updateQueue = finishedWork.updateQueue; - sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } - if (sourceFiber.tag === ClassComponent) { - var currentSourceFiber = sourceFiber.alternate; + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentNameFromFiber(finishedWork) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - if (currentSourceFiber === null) { - // This is a new mount. Change the tag so it's not mistaken for a - // completed class component. For example, we should not call - // componentWillUnmount if it is deleted. - sourceFiber.tag = IncompleteClassComponent; - } else { - // When we try rendering again, we should not reuse the current fiber, - // since it's known to be in an inconsistent state. Use a force update to - // prevent a bail out. - var update = createUpdate(NoTimestamp, SyncLane); - update.tag = ForceUpdate; - enqueueUpdate(sourceFiber, update); + commitUpdateQueue(finishedWork, updateQueue, instance); + } + + break; + } + + case HostRoot: { + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; + + if (_updateQueue !== null) { + var _instance = null; + + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; + + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; } - } // The source fiber did not complete. Mark it with Sync priority to - // indicate that it still has pending work. + } - sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } - return; - } // Confirmed that the boundary is in a concurrent mode tree. Continue - // with the normal suspend path. - // - // After this we'll use a set of heuristics to determine whether this - // render pass will run to completion or restart or "suspend" the commit. - // The actual logic for this is spread out in different places. - // - // This first principle is that if we're going to suspend when we complete - // a root, then we should also restart if we get an update or ping that - // might unsuspend it, and vice versa. The only reason to suspend is - // because you think you might want to restart before committing. However, - // it doesn't make sense to restart only while in the period we're suspended. - // - // Restarting too aggressively is also not good because it starves out any - // intermediate loading state. So we use heuristics to determine when. - // Suspense Heuristics - // - // If nothing threw a Promise or all the same fallbacks are already showing, - // then don't suspend/restart. - // - // If this is an initial render of a new tree of Suspense boundaries and - // those trigger a fallback, then don't suspend/restart. We want to ensure - // that we can show the initial loading state as quickly as possible. - // - // If we hit a "Delayed" case, such as when we'd switch from content back into - // a fallback, then we should always suspend/restart. Transitions apply - // to this case. If none is defined, JND is used instead. - // - // If we're already showing a fallback and it gets "retried", allowing us to show - // another level, but there's still an inner boundary that would show a fallback, - // then we suspend/restart for 500ms since the last time we showed a fallback - // anywhere in the tree. This effectively throttles progressive loading into a - // consistent train of commits. This also gives us an opportunity to restart to - // get to the completed state slightly earlier. - // - // If there's ambiguity due to batching it's resolved in preference of: - // 1) "delayed", 2) "initial render", 3) "retry". - // - // We want to ensure that a "busy" state doesn't get force committed. We want to - // ensure that new initial loading states can commit as soon as possible. + break; + } - attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; - _workInProgress.lanes = rootRenderLanes; - return; - } // This boundary already captured during this render. Continue to the next - // boundary. + case HostComponent: { + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. - _workInProgress = _workInProgress.return; - } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. - // TODO: Use invariant so the message is stripped in prod? + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + } - value = new Error( - (getComponentName(sourceFiber.type) || "A React component") + - " suspended while rendering, but no fallback UI was specified.\n" + - "\n" + - "Add a component higher in the tree to " + - "provide a loading indicator or placeholder to display." - ); - } // We didn't find a boundary that could handle this type of exception. Start - // over and traverse parent path again, this time treating the exception - // as an error. + break; + } - renderDidError(); - value = createCapturedValue(value, sourceFiber); - var workInProgress = returnFiber; + case HostText: { + // We have no life-cycles associated with text. + break; + } - do { - switch (workInProgress.tag) { - case HostRoot: { - var _errorInfo = value; - workInProgress.flags |= ShouldCapture; - var lane = pickArbitraryLane(rootRenderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + case HostPortal: { + // We have no life-cycles associated with portals. + break; + } - var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); + var phase = current === null ? "mount" : "update"; + + if (typeof onRender === "function") { + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime + ); + } + } - enqueueCapturedUpdate(workInProgress, _update); - return; + break; } - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var instance = workInProgress.stateNode; + case SuspenseComponent: { + break; + } - if ( - (workInProgress.flags & DidCapture) === NoFlags && - (typeof ctor.getDerivedStateFromError === "function" || - (instance !== null && - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance))) - ) { - workInProgress.flags |= ShouldCapture; + case SuspenseListComponent: + case IncompleteClassComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + break; - var _lane = pickArbitraryLane(rootRenderLanes); + default: { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + } - workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + { + if (finishedWork.flags & Ref) { + commitAttachRef(finishedWork); + } + } +} - var _update2 = createClassErrorUpdate( - workInProgress, - errorInfo, - _lane - ); +function hideOrUnhideAllChildren(finishedWork, isHidden) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (finishedWork.mode & ConcurrentMode) !== NoMode; + var current = finishedWork.alternate; + var wasHidden = current !== null && current.memoizedState !== null; // Only hide or unhide the top-most host nodes. - enqueueCapturedUpdate(workInProgress, _update2); - return; - } + var hostSubtreeRoot = null; - break; - } + { + // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. + var node = finishedWork; - workInProgress = workInProgress.return; - } while (workInProgress !== null); -} + while (true) { + if (node.tag === HostComponent) { + if (hostSubtreeRoot === null) { + hostSubtreeRoot = node; + var instance = node.stateNode; -var didWarnAboutUndefinedSnapshotBeforeUpdate = null; + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } + } + } else if (node.tag === HostText) { + if (hostSubtreeRoot === null) { + var _instance3 = node.stateNode; -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + if (isHidden) { + hideTextInstance(); + } else { + unhideTextInstance(_instance3, node.memoizedProps); + } + } + } else if ( + (node.tag === OffscreenComponent || + node.tag === LegacyHiddenComponent) && + node.memoizedState !== null && + node !== finishedWork + ); + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + if (node === finishedWork) { + return; + } -var callComponentWillUnmountWithTimer = function(current, instance) { - instance.props = current.memoizedProps; - instance.state = current.memoizedState; + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; + } - { - instance.componentWillUnmount(); - } -}; // Capture errors so they don't interrupt unmounting. + if (hostSubtreeRoot === node) { + hostSubtreeRoot = null; + } -function safelyCallComponentWillUnmount(current, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance - ); + node = node.return; + } - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + if (hostSubtreeRoot === node) { + hostSubtreeRoot = null; + } + + node.sibling.return = node.return; + node = node.sibling; } } } -function safelyDetachRef(current) { - var ref = current.ref; +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; + + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; + + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag + if (typeof ref === "function") { { - { - invokeGuardedCallback(null, ref, null, null); - } - - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); - } + ref(instanceToUse); } } else { - ref.current = null; + { + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentNameFromFiber(finishedWork) + ); + } + } + + ref.current = instanceToUse; } } } -function safelyCallDestroy(current, destroy) { - { - invokeGuardedCallback(null, destroy, null); +function commitDetachRef(current) { + var currentRef = current.ref; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, error); + if (currentRef !== null) { + if (typeof currentRef === "function") { + { + currentRef(null); + } + } else { + currentRef.current = null; } } -} +} // User-originating errors (lifecycles and refs) should not interrupt +// deletion, so don't let them throw. Host-originating errors should +// interrupt deletion, so it's okay -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { +function commitUnmount(finishedRoot, current, nearestMountedAncestor) { + onCommitUnmount(current); + + switch (current.tag) { case FunctionComponent: case ForwardRef: + case MemoComponent: case SimpleMemoComponent: { - return; - } + var updateQueue = current.updateQueue; - case ClassComponent: { - if (finishedWork.flags & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - var instance = finishedWork.stateNode; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + + if (destroy !== undefined) { + if ((tag & Layout) !== NoFlags$1) { + { + safelyCallDestroy(current, nearestMountedAncestor, destroy); + } } } - } - - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + effect = effect.next; + } while (effect !== firstEffect); + } + } - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); + return; + } - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); - } - } + case ClassComponent: { + safelyDetachRef(current, nearestMountedAncestor); + var instance = current.stateNode; - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance + ); } return; } - case HostRoot: { + case HostComponent: { + safelyDetachRef(current, nearestMountedAncestor); + return; + } + + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. { - if (finishedWork.flags & Snapshot) { - var root = finishedWork.stateNode; - clearContainer(root.containerInfo); - } + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } return; } - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types + case DehydratedFragment: { return; - } + } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + case ScopeComponent: { + return; + } } } -function commitHookEffectListUnmount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor) { + // While we're inside a removed host node we don't want to call + // removeChild on the inner nodes because they're removed by the top + // call anyway. We also want to call componentWillUnmount on all + // composites before this host node is removed from the tree. Therefore + // we do an inner loop while we're still inside the host node. + var node = root; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + while (true) { + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. + // Skip portals because commitUnmount() currently visits them recursively. - do { - if ((effect.tag & tag) === tag) { - // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + if ( + node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. + // If we don't use mutation we drill down into portals here instead. + node.tag !== HostPortal + ) { + node.child.return = node; + node = node.child; + continue; + } - if (destroy !== undefined) { - destroy(); - } + if (node === root) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; } - effect = effect.next; - } while (effect !== firstEffect); + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; } } -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; +function detachFiberMutation(fiber) { + // Cut off the return pointer to disconnect it from the tree. + // This enables us to detect and warn against state updates on an unmounted component. + // It also prevents events from bubbling from within disconnected components. + // + // Ideally, we should also clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. + // This child itself will be GC:ed when the parent updates the next time. + // + // Note that we can't clear child or sibling pointers yet. + // They're needed for passive effects and for findDOMNode. + // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). + // + // Don't reset the alternate yet, either. We need that so we can detach the + // alternate's fields in the passive phase. Clearing the return pointer is + // sufficient for findDOMNode semantics. + var alternate = fiber.alternate; - do { - if ((effect.tag & tag) === tag) { - // Mount - var create = effect.create; - effect.destroy = create(); + if (alternate !== null) { + alternate.return = null; + } - { - var destroy = effect.destroy; + fiber.return = null; +} - if (destroy !== undefined && typeof destroy !== "function") { - var addendum = void 0; +function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; - if (destroy === null) { - addendum = - " You returned null. If your effect does not require clean " + - "up, return undefined (or nothing)."; - } else if (typeof destroy.then === "function") { - addendum = - "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + - "Instead, write the async function inside your effect " + - "and call it immediately:\n\n" + - "useEffect(() => {\n" + - " async function fetchData() {\n" + - " // You can await here\n" + - " const response = await MyAPI.getData(someId);\n" + - " // ...\n" + - " }\n" + - " fetchData();\n" + - "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + - "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; - } else { - addendum = " You returned: " + destroy; - } + if (alternate !== null) { + fiber.alternate = null; + detachFiberAfterEffects(alternate); + } // Note: Defensively using negation instead of < in case + // `deletedTreeCleanUpLevel` is undefined. - error( - "An effect function must not return anything besides a function, " + - "which is used for clean-up.%s", - addendum - ); - } - } - } + { + // This is the default branch (level 0). + fiber.child = null; + fiber.deletions = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.sibling = null; + fiber.stateNode = null; + fiber.updateQueue = null; - effect = effect.next; - } while (effect !== firstEffect); + { + fiber._debugOwner = null; + } } } -function schedulePassiveEffects(finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; +function getHostParentFiber(fiber) { + var parent = fiber.return; - do { - var _effect = effect, - next = _effect.next, - tag = _effect.tag; + while (parent !== null) { + if (isHostParent(parent)) { + return parent; + } - if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); - enqueuePendingPassiveHookEffectMount(finishedWork, effect); - } + parent = parent.return; + } - effect = next; - } while (effect !== firstEffect); + { + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - // At this point layout effects have already been destroyed (during mutation phase). - // This is done to prevent sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. - { - commitHookEffectListMount(Layout | HasEffect, finishedWork); - } +function isHostParent(fiber) { + return ( + fiber.tag === HostComponent || + fiber.tag === HostRoot || + fiber.tag === HostPortal + ); +} - schedulePassiveEffects(finishedWork); - return; - } +function getHostSibling(fiber) { + // We're going to search forward into the tree until we find a sibling host + // node. Unfortunately, if multiple insertions are done in a row we have to + // search past them. This leads to exponential search for the next sibling. + // TODO: Find a more efficient way to do this. + var node = fiber; - case ClassComponent: { - var instance = finishedWork.stateNode; + siblings: while (true) { + // If we didn't find anything, let's try the next sibling. + while (node.sibling === null) { + if (node.return === null || isHostParent(node.return)) { + // If we pop out of the root or hit the parent the fiber we are the + // last sibling. + return null; + } - if (finishedWork.flags & Update) { - if (current === null) { - // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + node = node.return; + } - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + node.sibling.return = node.return; + node = node.sibling; - { - instance.componentDidMount(); - } - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + while ( + node.tag !== HostComponent && + node.tag !== HostText && + node.tag !== DehydratedFragment + ) { + // If it is not host node and, we might have a host node inside it. + // Try to search down until we find one. + if (node.flags & Placement) { + // If we don't have a child, try the siblings instead. + continue siblings; + } // If we don't have a child, try the siblings instead. + // We also skip portals because they are not part of this host tree. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (node.child === null || node.tag === HostPortal) { + continue siblings; + } else { + node.child.return = node; + node = node.child; + } + } // Check if this host node is stable or about to be placed. - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + if (!(node.flags & Placement)) { + // Found it! + return node.stateNode; + } + } +} - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - } - } // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. +function commitPlacement(finishedWork) { + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. - var updateQueue = finishedWork.updateQueue; + var parent; + var isContainer; + var parentStateNode = parentFiber.stateNode; - if (updateQueue !== null) { - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + switch (parentFiber.tag) { + case HostComponent: + parent = parentStateNode; + isContainer = false; + break; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + case HostRoot: + parent = parentStateNode.containerInfo; + isContainer = true; + break; - commitUpdateQueue(finishedWork, updateQueue, instance); - } + case HostPortal: + parent = parentStateNode.containerInfo; + isContainer = true; + break; + // eslint-disable-next-line-no-fallthrough - return; + default: { + throw Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); } + } - case HostRoot: { - // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. - var _updateQueue = finishedWork.updateQueue; + if (parentFiber.flags & ContentReset) { + parentFiber.flags &= ~ContentReset; + } - if (_updateQueue !== null) { - var _instance = null; + var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; + if (isContainer) { + insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); + } else { + insertOrAppendPlacementNode(finishedWork, before, parent); + } +} - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } +function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - commitUpdateQueue(finishedWork, _updateQueue, _instance); - } + if (isHost) { + var stateNode = node.stateNode; - return; + if (before) { + insertInContainerBefore(parent); + } else { + appendChildToContainer(parent, stateNode); } + } else if (tag === HostPortal); + else { + var child = node.child; - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. + if (child !== null) { + insertOrAppendPlacementNodeIntoContainer(child, before, parent); + var sibling = child.sibling; - if (current === null && finishedWork.flags & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; + while (sibling !== null) { + insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); + sibling = sibling.sibling; } - - return; } + } +} - case HostText: { - // We have no life-cycles associated with text. - return; - } +function insertOrAppendPlacementNode(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - case HostPortal: { - // We have no life-cycles associated with portals. - return; + if (isHost) { + var stateNode = node.stateNode; + + if (before) { + insertBefore(parent, stateNode, before); + } else { + appendChild(parent, stateNode); } + } else if (tag === HostPortal); + else { + var child = node.child; - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + if (child !== null) { + insertOrAppendPlacementNode(child, before, parent); + var sibling = child.sibling; - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - current === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } - } + while (sibling !== null) { + insertOrAppendPlacementNode(sibling, before, parent); + sibling = sibling.sibling; } - - return; - } - - case SuspenseComponent: { - return; } - - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - case OffscreenComponent: - case LegacyHiddenComponent: - return; - } - - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } } -function hideOrUnhideAllChildren(finishedWork, isHidden) { - { - // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. - var node = finishedWork; +function unmountHostComponents(finishedRoot, current, nearestMountedAncestor) { + // We only have the top Fiber that was deleted but we need to recurse down its + // children to find all the terminal nodes. + var node = current; // Each iteration, currentParent is populated with node's host parent if not + // currentParentIsValid. - while (true) { - if (node.tag === HostComponent) { - var instance = node.stateNode; + var currentParentIsValid = false; // Note: these two variables *must* always be updated together. - if (isHidden) { - hideInstance(instance); - } else { - unhideInstance(node.stateNode, node.memoizedProps); - } - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + var currentParent; + var currentParentIsContainer; - if (isHidden) { - hideTextInstance(); - } else { - unhideTextInstance(_instance3, node.memoizedProps); + while (true) { + if (!currentParentIsValid) { + var parent = node.return; + + findParent: while (true) { + if (!(parent !== null)) { + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); } - } else if ( - (node.tag === OffscreenComponent || - node.tag === LegacyHiddenComponent) && - node.memoizedState !== null && - node !== finishedWork - ); - else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - if (node === finishedWork) { - return; - } + var parentStateNode = parent.stateNode; - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - return; + switch (parent.tag) { + case HostComponent: + currentParent = parentStateNode; + currentParentIsContainer = false; + break findParent; + + case HostRoot: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; + + case HostPortal: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; } - node = node.return; + parent = parent.return; } - node.sibling.return = node.return; - node = node.sibling; + currentParentIsValid = true; } - } -} - -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; - - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; + if (node.tag === HostComponent || node.tag === HostText) { + commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the + // node from the tree. - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, node.stateNode); + } else { + removeChild(currentParent, node.stateNode); + } // Don't visit children because we already visited them. + } else if (node.tag === HostPortal) { + if (node.child !== null) { + // When we go into a portal, it becomes the parent to remove from. + // We will reassign it back when we pop the portal on the way up. + currentParent = node.stateNode.containerInfo; + currentParentIsContainer = true; // Visit children because portals might contain host components. - if (typeof ref === "function") { - { - ref(instanceToUse); + node.child.return = node; + node = node.child; + continue; } } else { - { - if (!ref.hasOwnProperty("current")) { - error( - "Unexpected ref object provided for %s. " + - "Use either a ref-setter function or React.createRef().", - getComponentName(finishedWork.type) - ); - } - } - - ref.current = instanceToUse; - } - } -} - -function commitDetachRef(current) { - var currentRef = current.ref; + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below. - if (currentRef !== null) { - if (typeof currentRef === "function") { - { - currentRef(null); + if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - } else { - currentRef.current = null; } - } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay -function commitUnmount(finishedRoot, current, renderPriorityLevel) { - onCommitUnmount(current); + if (node === current) { + return; + } - switch (current.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - var updateQueue = current.updateQueue; + while (node.sibling === null) { + if (node.return === null || node.return === current) { + return; + } - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; + node = node.return; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + if (node.tag === HostPortal) { + // When we go out of the portal, we need to restore the parent. + // Since we don't keep a stack of them, we will search for it. + currentParentIsValid = false; + } + } - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; + node.sibling.return = node.return; + node = node.sibling; + } +} - if (destroy !== undefined) { - if ((tag & Passive$1) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(current, effect); - } else { - { - safelyCallDestroy(current, destroy); - } - } - } +function commitDeletion(finishedRoot, current, nearestMountedAncestor) { + { + // Recursively delete all host nodes from the parent. + // Detach refs and call componentWillUnmount() on the whole subtree. + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); + } - effect = effect.next; - } while (effect !== firstEffect); - } + detachFiberMutation(current); +} + +function commitWork(current, finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); } return; } case ClassComponent: { - safelyDetachRef(current); - var instance = current.stateNode; - - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, instance); - } - return; } case HostComponent: { - safelyDetachRef(current); + var instance = finishedWork.stateNode; + + if (instance != null) { + // Commit the work prepared earlier. + var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + + var oldProps = current !== null ? current.memoizedProps : newProps; + var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; + + if (updatePayload !== null) { + commitUpdate(instance, updatePayload, type, oldProps, newProps); + } + } + return; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - unmountHostComponents(finishedRoot, current); + case HostText: { + if (!(finishedWork.stateNode !== null)) { + throw Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ); } + var textInstance = finishedWork.stateNode; + var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + + var oldText = current !== null ? current.memoizedProps : newText; + commitTextUpdate(textInstance, oldText, newText); return; } - case FundamentalComponent: { + case HostRoot: { return; } - case DehydratedFragment: { + case Profiler: { return; } - case ScopeComponent: { + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); return; } - } -} - -function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; - - while (true) { - commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. - if ( - node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. - // If we don't use mutation we drill down into portals here instead. - node.tag !== HostPortal - ) { - node.child.return = node; - node = node.child; - continue; + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; } - if (node === root) { + case IncompleteClassComponent: { return; } - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } - - node = node.return; + case ScopeComponent: { + break; } - node.sibling.return = node.return; - node = node.sibling; - } -} - -function detachFiberMutation(fiber) { - // Cut off the return pointers to disconnect it from the tree. Ideally, we - // should clear the child pointer of the parent alternate to let this - // get GC:ed but we don't know which for sure which parent is the current - // one so we'll settle for GC:ing the subtree of this child. This child - // itself will be GC:ed when the parent updates the next time. - // Note: we cannot null out sibling here, otherwise it can cause issues - // with findDOMNode and how it requires the sibling field to carry out - // traversal in a later effect. See PR #16820. We now clear the sibling - // field after effects, see: detachFiberAfterEffects. - // - // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. - // It may be required if the current component is an error boundary, - // and one of its descendants throws while unmounting a passive effect. - fiber.alternate = null; - fiber.child = null; - fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.return = null; - fiber.updateQueue = null; - - { - fiber._debugOwner = null; - } -} - -function getHostParentFiber(fiber) { - var parent = fiber.return; - - while (parent !== null) { - if (isHostParent(parent)) { - return parent; + case OffscreenComponent: + case LegacyHiddenComponent: { + var newState = finishedWork.memoizedState; + var isHidden = newState !== null; + hideOrUnhideAllChildren(finishedWork, isHidden); + return; } - - parent = parent.return; } { throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + "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 isHostParent(fiber) { - return ( - fiber.tag === HostComponent || - fiber.tag === HostRoot || - fiber.tag === HostPortal - ); -} - -function getHostSibling(fiber) { - // We're going to search forward into the tree until we find a sibling host - // node. Unfortunately, if multiple insertions are done in a row we have to - // search past them. This leads to exponential search for the next sibling. - // TODO: Find a more efficient way to do this. - var node = fiber; - - siblings: while (true) { - // If we didn't find anything, let's try the next sibling. - while (node.sibling === null) { - if (node.return === null || isHostParent(node.return)) { - // If we pop out of the root or hit the parent the fiber we are the - // last sibling. - return null; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; - - while ( - node.tag !== HostComponent && - node.tag !== HostText && - node.tag !== DehydratedFragment - ) { - // If it is not host node and, we might have a host node inside it. - // Try to search down until we find one. - if (node.flags & Placement) { - // If we don't have a child, try the siblings instead. - continue siblings; - } // If we don't have a child, try the siblings instead. - // We also skip portals because they are not part of this host tree. +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; - if (node.child === null || node.tag === HostPortal) { - continue siblings; - } else { - node.child.return = node; - node = node.child; - } - } // Check if this host node is stable or about to be placed. + if (newState !== null) { + markCommitTimeOfFallback(); - if (!(node.flags & Placement)) { - // Found it! - return node.stateNode; + { + // Hide the Offscreen component that contains the primary children. TODO: + // Ideally, this effect would have been scheduled on the Offscreen fiber + // itself. That's how unhiding works: the Offscreen component schedules an + // effect on itself. However, in this case, the component didn't complete, + // so the fiber was never added to the effect list in the normal path. We + // could have appended it to the effect list in the Suspense component's + // second pass, but doing it this way is less complicated. This would be + // simpler if we got rid of the effect list and traversed the tree, like + // we're planning to do. + var primaryChildParent = finishedWork.child; + hideOrUnhideAllChildren(primaryChildParent, true); } } } -function commitPlacement(finishedWork) { - var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. +function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; - var parent; - var isContainer; - var parentStateNode = parentFiber.stateNode; + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; - switch (parentFiber.tag) { - case HostComponent: - parent = parentStateNode; - isContainer = false; - break; + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + } - case HostRoot: - parent = parentStateNode.containerInfo; - isContainer = true; - break; + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - case HostPortal: - parent = parentStateNode.containerInfo; - isContainer = true; - break; + if (!retryCache.has(wakeable)) { + retryCache.add(wakeable); - case FundamentalComponent: + wakeable.then(retry, retry); + } + }); + } +} // This function detects when a Suspense boundary goes from visible to hidden. +// It returns false if the boundary is already hidden. +// TODO: Use an effect tag. - // eslint-disable-next-line-no-fallthrough +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + if (current !== null) { + var oldState = current.memoizedState; - default: { - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); + if (oldState === null || oldState.dehydrated !== null) { + var newState = finishedWork.memoizedState; + return newState !== null && newState.dehydrated === null; } } - if (parentFiber.flags & ContentReset) { - parentFiber.flags &= ~ContentReset; - } + return false; +} - var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. +function commitResetTextContent(current) { + resetTextContent(current.stateNode); +} - if (isContainer) { - insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); - } else { - insertOrAppendPlacementNode(finishedWork, before, parent); - } +function commitMutationEffects(root, firstChild, committedLanes) { + nextEffect = firstChild; + commitMutationEffects_begin(root); } -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; +function commitMutationEffects_begin(root) { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + var deletions = fiber.deletions; - if (before) { - insertInContainerBefore(parent); - } else { - appendChildToContainer(parent, stateNode); - } - } else if (tag === HostPortal); - else { - var child = node.child; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; - if (child !== null) { - insertOrAppendPlacementNodeIntoContainer(child, before, parent); - var sibling = child.sibling; + { + invokeGuardedCallback( + null, + commitDeletion, + null, + root, + childToDelete, + fiber + ); - while (sibling !== null) { - insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); - sibling = sibling.sibling; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(childToDelete, fiber, error); + } + } } } + + var child = fiber.child; + + if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitMutationEffects_complete(root); + } } } -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; +function commitMutationEffects_complete(root) { + while (nextEffect !== null) { + var fiber = nextEffect; + + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitMutationEffectsOnFiber, + null, + fiber, + root + ); - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } - if (before) { - insertBefore(parent, stateNode, before); - } else { - appendChild(parent, stateNode); + resetCurrentFiber(); } - } else if (tag === HostPortal); - else { - var child = node.child; - if (child !== null) { - insertOrAppendPlacementNode(child, before, parent); - var sibling = child.sibling; + var sibling = fiber.sibling; - while (sibling !== null) { - insertOrAppendPlacementNode(sibling, before, parent); - sibling = sibling.sibling; - } + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } + + nextEffect = fiber.return; } } -function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { - // We only have the top Fiber that was deleted but we need to recurse down its - // children to find all the terminal nodes. - var node = current; // Each iteration, currentParent is populated with node's host parent if not - // currentParentIsValid. +function commitMutationEffectsOnFiber(finishedWork, root) { + var flags = finishedWork.flags; - var currentParentIsValid = false; // Note: these two variables *must* always be updated together. + if (flags & ContentReset) { + commitResetTextContent(finishedWork); + } - var currentParent; - var currentParentIsContainer; + if (flags & Ref) { + var current = finishedWork.alternate; - while (true) { - if (!currentParentIsValid) { - var parent = node.return; + if (current !== null) { + commitDetachRef(current); + } + } // The following switch statement is only concerned about placement, + // updates, and deletions. To avoid needing to add a case for every possible + // bitmap value, we remove the secondary effects from the effect tag and + // switch on that value. - findParent: while (true) { - if (!(parent !== null)) { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + var primaryFlags = flags & (Placement | Update | Hydrating); - var parentStateNode = parent.stateNode; + switch (primaryFlags) { + case Placement: { + commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. - switch (parent.tag) { - case HostComponent: - currentParent = parentStateNode; - currentParentIsContainer = false; - break findParent; + finishedWork.flags &= ~Placement; + break; + } - case HostRoot: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; + case PlacementAndUpdate: { + // Placement + commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. - case HostPortal: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; - } + finishedWork.flags &= ~Placement; // Update - parent = parent.return; - } + var _current = finishedWork.alternate; + commitWork(_current, finishedWork); + break; + } - currentParentIsValid = true; + case Hydrating: { + finishedWork.flags &= ~Hydrating; + break; } - if (node.tag === HostComponent || node.tag === HostText) { - commitNestedUnmounts(finishedRoot, node); // After all the children have unmounted, it is now safe to remove the - // node from the tree. + case HydratingAndUpdate: { + finishedWork.flags &= ~Hydrating; // Update - if (currentParentIsContainer) { - removeChildFromContainer(currentParent, node.stateNode); - } else { - removeChild(currentParent, node.stateNode); - } // Don't visit children because we already visited them. - } else if (node.tag === HostPortal) { - if (node.child !== null) { - // When we go into a portal, it becomes the parent to remove from. - // We will reassign it back when we pop the portal on the way up. - currentParent = node.stateNode.containerInfo; - currentParentIsContainer = true; // Visit children because portals might contain host components. + var _current2 = finishedWork.alternate; + commitWork(_current2, finishedWork); + break; + } - node.child.return = node; - node = node.child; - continue; - } + case Update: { + var _current3 = finishedWork.alternate; + commitWork(_current3, finishedWork); + break; + } + } +} + +function commitLayoutEffects(finishedWork, root, committedLanes) { + nextEffect = finishedWork; + commitLayoutEffects_begin(finishedWork, root, committedLanes); +} + +function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; + + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; + + if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; } else { - commitUnmount(finishedRoot, node); // Visit children because we may find more host components below. + commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + } + } +} - if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; +function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; + + while (nextEffect !== null) { + var fiber = nextEffect; + + if ((fiber.flags & LayoutMask) !== NoFlags) { + var current = fiber.alternate; + + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitLayoutEffectOnFiber, + null, + root, + current, + fiber, + committedLanes + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); } } - if (node === current) { + if (fiber === subtreeRoot) { + nextEffect = null; return; } - while (node.sibling === null) { - if (node.return === null || node.return === current) { - return; - } - - node = node.return; + var sibling = fiber.sibling; - if (node.tag === HostPortal) { - // When we go out of the portal, we need to restore the parent. - // Since we don't keep a stack of them, we will search for it. - currentParentIsValid = false; - } + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - node.sibling.return = node.return; - node = node.sibling; + nextEffect = fiber.return; } } -function commitDeletion(finishedRoot, current, renderPriorityLevel) { - { - // Recursively delete all host nodes from the parent. - // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current); - } +function commitPassiveMountEffects(root, finishedWork) { + nextEffect = finishedWork; + commitPassiveMountEffects_begin(finishedWork, root); +} - var alternate = current.alternate; - detachFiberMutation(current); +function commitPassiveMountEffects_begin(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; - if (alternate !== null) { - detachFiberMutation(alternate); + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitPassiveMountEffects_complete(subtreeRoot, root); + } } } -function commitWork(current, finishedWork) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - // Layout effects are destroyed during the mutation phase so that all - // destroy functions for all fibers are called before any create functions. - // This prevents sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. +function commitPassiveMountEffects_complete(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; + + if ((fiber.flags & Passive) !== NoFlags) { { - commitHookEffectListUnmount(Layout | HasEffect, finishedWork); - } + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitPassiveMountOnFiber, + null, + root, + fiber + ); - return; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); + } } - case ClassComponent: { + if (fiber === subtreeRoot) { + nextEffect = null; return; } - case HostComponent: { - var instance = finishedWork.stateNode; - - if (instance != null) { - // Commit the work prepared earlier. - var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. + var sibling = fiber.sibling; - var oldProps = current !== null ? current.memoizedProps : newProps; - var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; + nextEffect = fiber.return; + } +} - if (updatePayload !== null) { - commitUpdate(instance, updatePayload, type, oldProps, newProps); - } +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); } - return; + break; } + } +} - case HostText: { - if (!(finishedWork.stateNode !== null)) { - throw Error( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } +function commitPassiveUnmountEffects(firstChild) { + nextEffect = firstChild; + commitPassiveUnmountEffects_begin(); +} + +function commitPassiveUnmountEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; + var child = fiber.child; + + if ((nextEffect.flags & ChildDeletion) !== NoFlags) { + var deletions = fiber.deletions; + + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + nextEffect = fiberToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + fiberToDelete, + fiber + ); + } - var textInstance = finishedWork.stateNode; - var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. + { + // A fiber was deleted from this parent fiber, but it's still part of + // the previous (alternate) parent fiber's list of children. Because + // children are a linked list, an earlier sibling that's still alive + // will be connected to the deleted fiber via its `alternate`: + // + // live fiber + // --alternate--> previous live fiber + // --sibling--> deleted fiber + // + // We can't disconnect `alternate` on nodes that haven't been deleted + // yet, but we can disconnect the `sibling` and `child` pointers. + var previousFiber = fiber.alternate; - var oldText = current !== null ? current.memoizedProps : newText; - commitTextUpdate(textInstance, oldText, newText); - return; - } + if (previousFiber !== null) { + var detachedChild = previousFiber.child; - case HostRoot: { - return; - } + if (detachedChild !== null) { + previousFiber.child = null; - case Profiler: { - return; - } + do { + var detachedSibling = detachedChild.sibling; + detachedChild.sibling = null; + detachedChild = detachedSibling; + } while (detachedChild !== null); + } + } + } - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; + nextEffect = fiber; + } } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffects_complete(); } + } +} - case IncompleteClassComponent: { - return; - } +function commitPassiveUnmountEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - case FundamentalComponent: { - break; + if ((fiber.flags & Passive) !== NoFlags) { + setCurrentFiber(fiber); + commitPassiveUnmountOnFiber(fiber); + resetCurrentFiber(); } - case ScopeComponent: { - break; - } + var sibling = fiber.sibling; - case OffscreenComponent: - case LegacyHiddenComponent: { - var newState = finishedWork.memoizedState; - var isHidden = newState !== null; - hideOrUnhideAllChildren(finishedWork, isHidden); + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; return; } - } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + nextEffect = fiber.return; } } -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; - - if (newState !== null) { - markCommitTimeOfFallback(); +function commitPassiveUnmountOnFiber(finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount( + Passive$1 | HasEffect, + finishedWork, + finishedWork.return + ); + } - { - // Hide the Offscreen component that contains the primary children. TODO: - // Ideally, this effect would have been scheduled on the Offscreen fiber - // itself. That's how unhiding works: the Offscreen component schedules an - // effect on itself. However, in this case, the component didn't complete, - // so the fiber was never added to the effect list in the normal path. We - // could have appended it to the effect list in the Suspense component's - // second pass, but doing it this way is less complicated. This would be - // simpler if we got rid of the effect list and traversed the tree, like - // we're planning to do. - var primaryChildParent = finishedWork.child; - hideOrUnhideAllChildren(primaryChildParent, true); + break; } } } -function attachSuspenseRetryListeners(finishedWork) { - // If this boundary just timed out, then it will have a set of wakeables. - // For each wakeable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. - var wakeables = finishedWork.updateQueue; +function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + deletedSubtreeRoot, + nearestMountedAncestor +) { + while (nextEffect !== null) { + var fiber = nextEffect; // Deletion effects fire in parent -> child order + // TODO: Check if fiber has a PassiveStatic flag - if (wakeables !== null) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we + // do this, still need to handle `deletedTreeCleanUpLevel` correctly.) - if (retryCache === null) { - retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + if (child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ); } + } +} - wakeables.forEach(function(wakeable) { - // Memoize using the boundary fiber to prevent redundant listeners. - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - - if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } +function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot +) { + while (nextEffect !== null) { + var fiber = nextEffect; + var sibling = fiber.sibling; + var returnFiber = fiber.return; - retryCache.add(wakeable); - wakeable.then(retry, retry); + { + // This is the default branch (level 0). We do not recursively clear all + // the fiber fields. Only the root of the deleted subtree. + if (fiber === deletedSubtreeRoot) { + detachFiberAfterEffects(fiber); + nextEffect = null; + return; } - }); + } + + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, returnFiber); + nextEffect = sibling; + return; + } + + nextEffect = returnFiber; } -} // This function detects when a Suspense boundary goes from visible to hidden. -// It returns false if the boundary is already hidden. -// TODO: Use an effect tag. +} -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - if (current !== null) { - var oldState = current.memoizedState; +function commitPassiveUnmountInsideDeletedTreeOnFiber( + current, + nearestMountedAncestor +) { + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); + } - if (oldState === null || oldState.dehydrated !== null) { - var newState = finishedWork.memoizedState; - return newState !== null && newState.dehydrated === null; + break; } } - - return false; } -function commitResetTextContent(current) { - resetTextContent(current.stateNode); +var didWarnWrongReturnPointer = false; + +function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { + { + if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { + didWarnWrongReturnPointer = true; + + error( + "Internal React error: Return pointer is inconsistent " + "with parent." + ); + } + } // TODO: Remove this assignment once we're confident that it won't break + // anything, by checking the warning logs for the above invariant + + fiber.return = expectedReturnFiber; } var COMPONENT_TYPE = 0; @@ -17426,6 +18423,7 @@ if (typeof Symbol === "function" && Symbol.for) { var ceil = Math.ceil; var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ @@ -17433,21 +18431,18 @@ var NoContext = var BatchedContext = /* */ 1; -var DiscreteEventContext = - /* */ - 4; var LegacyUnbatchedContext = /* */ - 8; + 4; var RenderContext = /* */ - 16; + 8; var CommitContext = /* */ - 32; + 16; var RetryAfterError = /* */ - 64; + 32; var RootIncomplete = 0; var RootFatalErrored = 1; var RootErrored = 2; @@ -17487,8 +18482,7 @@ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. -var workInProgressRootPingedLanes = NoLanes; -var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train +var workInProgressRootPingedLanes = NoLanes; // The most recent time we committed a fallback. This lets us ensure a train // model where we don't commit new loading states in too quick succession. var globalMostRecentFallbackTime = 0; @@ -17507,40 +18501,26 @@ function resetRenderTimer() { function getRenderTargetTime() { return workInProgressRootRenderTargetTime; } -var nextEffect = null; var hasUncaughtError = false; var firstUncaughtError = null; -var legacyErrorBoundariesThatAlreadyFailed = null; +var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; -var pendingPassiveEffectsRenderPriority = NoPriority$1; var pendingPassiveEffectsLanes = NoLanes; -var pendingPassiveHookEffectsMount = []; -var pendingPassiveHookEffectsUnmount = []; -var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; var nestedUpdateCount = 0; var rootWithNestedUpdates = null; var NESTED_PASSIVE_UPDATE_LIMIT = 50; -var nestedPassiveUpdateCount = 0; // Marks the need to reschedule pending interactions at these lanes -// 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. -// TODO: Can use a bitmask instead of an array - -var spawnedWorkDuringRender = null; // If two updates are scheduled within the same event, we should treat their +var nestedPassiveUpdateCount = 0; // If two updates are scheduled within the same event, we should treat their // event times as simultaneous, even if the actual clock time has advanced // between the first and second call. var currentEventTime = NoTimestamp; -var currentEventWipLanes = NoLanes; -var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. +var currentEventTransitionLane = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. // We warn about state updates for unmounted components differently in this case. var isFlushingPassiveEffects = false; -var focusedInstanceHandle = null; -var shouldFireAfterActiveInstanceBlur = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -17562,69 +18542,46 @@ function requestUpdateLane(fiber) { // Special cases var mode = fiber.mode; - if ((mode & BlockingMode) === NoMode) { + if ((mode & ConcurrentMode) === NoMode) { return SyncLane; - } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 - ? SyncLane - : SyncBatchedLane; - } // The algorithm for assigning an update to a lane should be stable for all - // updates at the same priority within the same event. To do this, the inputs - // to the algorithm must be the same. For example, we use the `renderLanes` - // to avoid choosing a lane that is already in the middle of rendering. - // - // However, the "included" lanes could be mutated in between updates in the - // same event, like if you perform an update inside `flushSync`. Or any other - // code path that might call `prepareFreshStack`. - // - // The trick we use is to cache the first of each of these inputs within an - // event. Then reset the cached values once we can be sure the event is over. - // Our heuristic for that is whenever we enter a concurrent work loop. - // - // We'll do the same for `currentEventPendingLanes` below. - - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; } var isTransition = requestCurrentTransition() !== NoTransition; if (isTransition) { - if (currentEventPendingLanes !== NoLanes) { - currentEventPendingLanes = - mostRecentlyUpdatedRoot !== null - ? mostRecentlyUpdatedRoot.pendingLanes - : NoLanes; + // The algorithm for assigning an update to a lane should be stable for all + // updates at the same priority within the same event. To do this, the + // inputs to the algorithm must be the same. + // + // The trick we use is to cache the first of each of these inputs within an + // event. Then reset the cached values once we can be sure the event is + // over. Our heuristic for that is whenever we enter a concurrent work loop. + if (currentEventTransitionLane === NoLane) { + // All transitions within the same event are assigned the same lane. + currentEventTransitionLane = claimNextTransitionLane(); } - return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); - } // TODO: Remove this dependency on the Scheduler priority. - // To do that, we're replacing it with an update lane priority. - - var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. - // This couples React to the Scheduler internals, so we're replacing it - // with the currentUpdateLanePriority above. As an example of how this - // could be problematic, if we're not inside `Scheduler.runWithPriority`, - // then we'll get the priority of the current running Scheduler task, - // which is probably not what we want. - - var lane; + return currentEventTransitionLane; + } // Updates originating inside certain React methods, like flushSync, have + // their priority set by tracking it with a context variable. + // + // The opaque type returned by the host config is internally a lane, so we can + // use that directly. + // TODO: Move this type conversion to the event priority module. - if ( - // TODO: Temporary. We're removing the concept of discrete updates. - (executionContext & DiscreteEventContext) !== NoContext && - schedulerPriority === UserBlockingPriority$1 - ) { - lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); - } else { - var schedulerLanePriority = schedulerPriorityToLanePriority( - schedulerPriority - ); + var updateLane = getCurrentUpdatePriority(); - lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); - } + if (updateLane !== NoLane) { + return updateLane; + } // This update originated outside React. Ask the host environement for an + // appropriate priority, based on the type of event. + // + // The opaque type returned by the host config is internally a lane, so we can + // use that directly. + // TODO: Move this type conversion to the event priority module. - return lane; + var eventLane = getCurrentEventPriority(); + return eventLane; } function requestRetryLane(fiber) { @@ -17634,19 +18591,11 @@ function requestRetryLane(fiber) { // Special cases var mode = fiber.mode; - if ((mode & BlockingMode) === NoMode) { + if ((mode & ConcurrentMode) === NoMode) { return SyncLane; - } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 - ? SyncLane - : SyncBatchedLane; - } // See `requestUpdateLane` for explanation of `currentEventWipLanes` - - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; } - return findRetryLane(currentEventWipLanes); + return claimNextRetryLane(); } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -17657,7 +18606,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (root === null) { warnAboutUpdateOnUnmountedFiberInDEV(fiber); return null; - } // Mark that the root has a pending update. + } markRootUpdated(root, lane, eventTime); @@ -17683,10 +18632,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { // already started rendering. markRootSuspended$1(root, workInProgressRootRenderLanes); } - } // TODO: requestUpdateLanePriority also reads the priority. Pass the - // priority as an argument to that function and this one. - - var priorityLevel = getCurrentPriorityLevel(); + } if (lane === SyncLane) { if ( @@ -17694,52 +18640,32 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { (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, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed + // 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. - performSyncWorkOnRoot(root); } else { ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, lane); - if (executionContext === NoContext) { + if ( + executionContext === NoContext && + (fiber.mode & ConcurrentMode) === NoMode + ) { // Flush the synchronous work now, unless 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-initiated // updates, to preserve historical behavior of legacy mode. resetRenderTimer(); - flushSyncCallbackQueue(); + flushSyncCallbacksOnlyInLegacyMode(); } } } else { - // Schedule a discrete update but only if it's not Sync. - if ( - (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered - // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority$1 || - priorityLevel === ImmediatePriority$1) - ) { - // 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 Set([root]); - } else { - rootsWithPendingDiscreteUpdates.add(root); - } - } // Schedule other updates after in case the callback is sync. - + // Schedule other updates after in case the callback is sync. ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, lane); - } // We use this when assigning a lane for a transition inside - // `requestUpdateLane`. We assume it's the same as the root being updated, - // since in the common case of a single root app it probably is. If it's not - // the same root, then it's not a huge deal, we just might batch more stuff - // together more than necessary. - - mostRecentlyUpdatedRoot = root; + } + + return root; } // This is split into a separate function so we can mark a fiber with pending // work without treating it as a typical update that originates from an event; // e.g. retrying a Suspense boundary isn't an update, but it does schedule work @@ -17761,7 +18687,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { ) { warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - } // Walk the parent path to the root and update the child expiration time. + } // Walk the parent path to the root and update the child lanes. var node = sourceFiber; var parent = sourceFiber.return; @@ -17790,6 +18716,20 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { } else { return null; } +} + +function isInterleavedUpdate(fiber, lane) { + return ( + // TODO: Optimize slightly by comparing to root that fiber belongs to. + // Requires some refactoring. Not a big deal though since it's rare for + // concurrent apps to have more than a single root. + workInProgressRoot !== null && + (fiber.mode & ConcurrentMode) !== NoMode && // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps), + // then don't treat this as an interleaved update. This pattern is + // accompanied by a warning but we haven't fully deprecated it yet. We can + // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled. + deferRenderPhaseUpdateToNextBatch + ); } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the priority // of the existing task is the same as the priority of the next level that the @@ -17805,50 +18745,88 @@ function ensureRootIsScheduled(root, currentTime) { var nextLanes = getNextLanes( root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes - ); // This returns the priority level computed during the `getNextLanes` call. - - var newCallbackPriority = returnNextLanesPriority(); + ); if (nextLanes === NoLanes) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); - root.callbackNode = null; - root.callbackPriority = NoLanePriority; } + root.callbackNode = null; + root.callbackPriority = NoLane; return; - } // Check if there's an existing task. We may be able to reuse it. + } // We use the highest priority lane to represent the priority of the callback. - if (existingCallbackNode !== null) { - var existingCallbackPriority = root.callbackPriority; + var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it. - if (existingCallbackPriority === newCallbackPriority) { - // The priority hasn't changed. We can reuse the existing task. Exit. - return; - } // The priority changed. Cancel the existing callback. We'll schedule a new - // one below. + var existingCallbackPriority = root.callbackPriority; + + if (existingCallbackPriority === newCallbackPriority) { + { + // If we're going to re-use an existing task, it needs to exist. + // Assume that discrete update microtasks are non-cancellable and null. + // TODO: Temporary until we confirm this warning is not fired. + if ( + existingCallbackNode == null && + existingCallbackPriority !== SyncLane + ) { + error( + "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue." + ); + } + } // The priority hasn't changed. We can reuse the existing task. Exit. + + return; + } + if (existingCallbackNode != null) { + // Cancel the existing callback. We'll schedule a new one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. var newCallbackNode; - if (newCallbackPriority === SyncLanePriority) { + if (newCallbackPriority === SyncLane) { // Special case: Sync React callbacks are scheduled on a special // internal queue - newCallbackNode = scheduleSyncCallback( - performSyncWorkOnRoot.bind(null, root) - ); - } else if (newCallbackPriority === SyncBatchedLanePriority) { - newCallbackNode = scheduleCallback( - ImmediatePriority$1, - performSyncWorkOnRoot.bind(null, root) - ); + if (root.tag === LegacyRoot) { + scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else { + scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + } + + { + // Flush the queue in an Immediate task. + scheduleCallback(ImmediatePriority, flushSyncCallbacks); + } + + newCallbackNode = null; } else { - var schedulerPriorityLevel = lanePriorityToSchedulerPriority( - newCallbackPriority - ); + var schedulerPriorityLevel; + + switch (lanesToEventPriority(nextLanes)) { + case DiscreteEventPriority: + schedulerPriorityLevel = ImmediatePriority; + break; + + case ContinuousEventPriority: + schedulerPriorityLevel = UserBlockingPriority; + break; + + case DefaultEventPriority: + schedulerPriorityLevel = NormalPriority; + break; + + case IdleEventPriority: + schedulerPriorityLevel = IdlePriority; + break; + + default: + schedulerPriorityLevel = NormalPriority; + break; + } + newCallbackNode = scheduleCallback( schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root) @@ -17860,12 +18838,11 @@ function ensureRootIsScheduled(root, currentTime) { } // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root) { - // Since we know we're in a React event, we can clear the current +function performConcurrentWorkOnRoot(root, didTimeout) { // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; + currentEventTransitionLane = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { throw Error("Should not already be working."); @@ -17895,40 +18872,41 @@ function performConcurrentWorkOnRoot(root) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; - } - - var exitStatus = renderRootConcurrent(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack(root, NoLanes); - } else if (exitStatus !== RootIncomplete) { + } // We disable time-slicing in some cases: if the work has been CPU-bound + // for too long ("expired" work, to prevent starvation), or we're in + // sync-updates-by-default mode. + // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + + var exitStatus = + shouldTimeSlice(root, lanes) && !didTimeout + ? renderRootConcurrent(root, lanes) + : renderRootSync(root, lanes); + + if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. if (root.hydrate) { root.hydrate = false; + + { + errorHydratingContainer(root.containerInfo); + } + clearContainer(root.containerInfo); } // If something threw an error, try rendering one more time. We'll render // synchronously to block concurrent data mutations, and we'll includes // all pending updates are included. If it still fails after the second // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { - exitStatus = renderRootSync(root, lanes); + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = renderRootSync(root, errorRetryLanes); } } @@ -18092,56 +19070,38 @@ function performSyncWorkOnRoot(root) { throw Error("Should not already be working."); } - flushPassiveEffects(); - var lanes; - var exitStatus; - - if ( - root === workInProgressRoot && - includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes) - ) { - // There's a partial tree, and at least one of its lanes has expired. Finish - // rendering it before rendering the rest of the expired work. - lanes = workInProgressRootRenderLanes; - exitStatus = renderRootSync(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // Note that this only happens when part of the tree is rendered - // concurrently. If the whole tree is rendered synchronously, then there - // are no interleaved events. - lanes = getNextLanes(root, lanes); - exitStatus = renderRootSync(root, lanes); - } - } else { - lanes = getNextLanes(root, NoLanes); - exitStatus = renderRootSync(root, lanes); + flushPassiveEffects(); + var lanes = getNextLanes(root, NoLanes); + + if (!includesSomeLane(lanes, SyncLane)) { + // There's no remaining sync work left. + ensureRootIsScheduled(root, now()); + return null; } + var exitStatus = renderRootSync(root, lanes); + if (root.tag !== LegacyRoot && exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. if (root.hydrate) { root.hydrate = false; + + { + errorHydratingContainer(root.containerInfo); + } + clearContainer(root.containerInfo); } // If something threw an error, try rendering one more time. We'll render // synchronously to block concurrent data mutations, and we'll includes // all pending updates are included. If it still fails after the second // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; exitStatus = renderRootSync(root, lanes); } } @@ -18164,7 +19124,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } - function batchedUpdates$1(fn, a) { var prevExecutionContext = executionContext; executionContext |= BatchedContext; @@ -18172,45 +19131,47 @@ function batchedUpdates$1(fn, a) { try { return fn(a); } finally { - executionContext = prevExecutionContext; + executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer + // most batchedUpdates-like method. if (executionContext === NoContext) { - // Flush the immediate callbacks that were scheduled during this batch resetRenderTimer(); - flushSyncCallbackQueue(); + flushSyncCallbacksOnlyInLegacyMode(); } } } function flushSync(fn, a) { var prevExecutionContext = executionContext; - - if ((prevExecutionContext & (RenderContext | CommitContext)) !== NoContext) { - { - error( - "flushSync was called from inside a lifecycle method. React cannot " + - "flush when React is already rendering. Consider moving this call to " + - "a scheduler task or micro task." - ); - } - - return fn(a); - } - executionContext |= BatchedContext; + var prevTransition = ReactCurrentBatchConfig$2.transition; + var previousPriority = getCurrentUpdatePriority(); - { - try { - if (fn) { - return runWithPriority(ImmediatePriority$1, fn.bind(null, a)); - } else { - return undefined; - } - } finally { - 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. + try { + ReactCurrentBatchConfig$2.transition = 0; + setCurrentUpdatePriority(DiscreteEventPriority); - flushSyncCallbackQueue(); + if (fn) { + return fn(a); + } else { + return undefined; + } + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; + 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. + + if ((executionContext & (RenderContext | CommitContext)) === NoContext) { + flushSyncCallbacks(); + } else { + { + error( + "flushSync was called from inside a lifecycle method. React cannot " + + "flush when React is already rendering. Consider moving this call to " + + "a scheduler task or micro task." + ); + } } } } @@ -18257,10 +19218,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootSkippedLanes = NoLanes; workInProgressRootUpdatedLanes = NoLanes; workInProgressRootPingedLanes = NoLanes; - - { - spawnedWorkDuringRender = null; - } + enqueueInterleavedUpdates(); { ReactStrictModeWarnings.discardPendingWarnings(); @@ -18350,20 +19308,6 @@ function popDispatcher(prevDispatcher) { ReactCurrentDispatcher$2.current = prevDispatcher; } -function pushInteractions(root) { - { - var prevInteractions = tracing.__interactionsRef.current; - tracing.__interactionsRef.current = root.memoizedInteractions; - return prevInteractions; - } -} - -function popInteractions(prevInteractions) { - { - tracing.__interactionsRef.current = prevInteractions; - } -} - function markCommitTimeOfFallback() { globalMostRecentFallbackTime = now(); } @@ -18423,11 +19367,8 @@ function renderRootSync(root, lanes) { if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { prepareFreshStack(root, lanes); - startWorkOnPendingInteractions(root, lanes); } - var prevInteractions = pushInteractions(root); - do { try { workLoopSync(); @@ -18438,11 +19379,6 @@ function renderRootSync(root, lanes) { } while (true); resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - executionContext = prevExecutionContext; popDispatcher(prevDispatcher); @@ -18478,11 +19414,8 @@ function renderRootConcurrent(root, lanes) { if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { resetRenderTimer(); prepareFreshStack(root, lanes); - startWorkOnPendingInteractions(root, lanes); } - var prevInteractions = pushInteractions(root); - do { try { workLoopConcurrent(); @@ -18493,11 +19426,6 @@ function renderRootConcurrent(root, lanes) { } while (true); resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - popDispatcher(prevDispatcher); executionContext = prevExecutionContext; @@ -18580,47 +19508,6 @@ function completeUnitOfWork(unitOfWork) { workInProgress = next; return; } - - resetChildLanes(completedWork); - - if ( - returnFiber !== null && // Do not append effects to parents if a sibling failed to complete - (returnFiber.flags & Incomplete) === NoFlags - ) { - // Append all the effects of the subtree and this fiber onto the effect - // list of the parent. The completion order of the children affects the - // side-effect order. - if (returnFiber.firstEffect === null) { - returnFiber.firstEffect = completedWork.firstEffect; - } - - if (completedWork.lastEffect !== null) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork.firstEffect; - } - - returnFiber.lastEffect = completedWork.lastEffect; - } // If this fiber had side-effects, we append it AFTER the children's - // side-effects. We can perform certain side-effects earlier if needed, - // by doing multiple passes over the effect list. We don't want to - // schedule our own side-effect on our own list because if end up - // reusing children we'll schedule this effect onto itself since we're - // at the end. - - var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect - // list. PerformedWork effect is read by React DevTools but shouldn't be - // committed. - - if (flags > PerformedWork) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork; - } else { - returnFiber.firstEffect = completedWork; - } - - returnFiber.lastEffect = completedWork; - } - } } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -18653,9 +19540,10 @@ function completeUnitOfWork(unitOfWork) { } if (returnFiber !== null) { - // Mark the parent fiber as incomplete and clear its effect list. - returnFiber.firstEffect = returnFiber.lastEffect = null; + // Mark the parent fiber as incomplete and clear its subtree flags. returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags; + returnFiber.deletions = null; } } @@ -18677,90 +19565,21 @@ function completeUnitOfWork(unitOfWork) { } } -function resetChildLanes(completedWork) { - if ( - // TODO: Move this check out of the hot path by moving `resetChildLanes` - // to switch statement in `completeWork`. - (completedWork.tag === LegacyHiddenComponent || - completedWork.tag === OffscreenComponent) && - completedWork.memoizedState !== null && - !includesSomeLane(subtreeRenderLanes, OffscreenLane) && - (completedWork.mode & ConcurrentMode) !== NoLanes - ) { - // The children of this component are hidden. Don't bubble their - // expiration times. - return; - } - - var newChildLanes = NoLanes; // Bubble up the earliest expiration time. - - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var actualDuration = completedWork.actualDuration; - var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will - // only be updated if work is done on the fiber (i.e. it doesn't bailout). - // When work is done, it should bubble to the parent's actualDuration. If - // the fiber has not been cloned though, (meaning no work was done), then - // this value will reflect the amount of time spent working on a previous - // render. In that case it should not bubble. We determine whether it was - // cloned by comparing the child pointer. - - var shouldBubbleActualDurations = - completedWork.alternate === null || - completedWork.child !== completedWork.alternate.child; - var child = completedWork.child; - - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - - if (shouldBubbleActualDurations) { - actualDuration += child.actualDuration; - } - - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - var isTimedOutSuspense = - completedWork.tag === SuspenseComponent && - completedWork.memoizedState !== null; - - if (isTimedOutSuspense) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var primaryChildFragment = completedWork.child; - - if (primaryChildFragment !== null) { - treeBaseDuration -= primaryChildFragment.treeBaseDuration; - } - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; +function commitRoot(root) { + // TODO: This no longer makes any sense. We already wrap the mutation and + // layout phases. Should be able to remove. + var previousUpdateLanePriority = getCurrentUpdatePriority(); + var prevTransition = ReactCurrentBatchConfig$2.transition; - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - _child = _child.sibling; - } + try { + ReactCurrentBatchConfig$2.transition = 0; + setCurrentUpdatePriority(DiscreteEventPriority); + commitRootImpl(root, previousUpdateLanePriority); + } finally { + ReactCurrentBatchConfig$2.transition = prevTransition; + setCurrentUpdatePriority(previousUpdateLanePriority); } - completedWork.childLanes = newChildLanes; -} - -function commitRoot(root) { - var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority( - ImmediatePriority$1, - commitRootImpl.bind(null, root, renderPriorityLevel) - ); return null; } @@ -18786,6 +19605,15 @@ function commitRootImpl(root, renderPriorityLevel) { if (finishedWork === null) { return null; + } else { + { + if (lanes === NoLanes) { + error( + "root.finishedLanes should not be empty during a commit. This is a " + + "bug in React." + ); + } + } } root.finishedWork = null; @@ -18798,52 +19626,57 @@ function commitRootImpl(root, renderPriorityLevel) { } // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. - root.callbackNode = null; // Update the first and last pending times on this root. The new first + root.callbackNode = null; + root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); - markRootFinished(root, remainingLanes); // Clear already finished discrete updates in case that a later call of - // `flushDiscreteUpdates` starts a useless render pass which may cancels - // a scheduled timeout. - - if (rootsWithPendingDiscreteUpdates !== null) { - if ( - !hasDiscreteLanes(remainingLanes) && - rootsWithPendingDiscreteUpdates.has(root) - ) { - rootsWithPendingDiscreteUpdates.delete(root); - } - } + markRootFinished(root, remainingLanes); if (root === workInProgressRoot) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; workInProgressRootRenderLanes = NoLanes; - } // Get the list of effects. - - var firstEffect; - - if (finishedWork.flags > PerformedWork) { - // A fiber's effect list consists only of its children, not itself. So if - // the root has an effect, we need to add it to the end of the list. The - // resulting list is the set that would belong to the root's parent, if it - // had one; that is, all the effects in the tree including the root. - if (finishedWork.lastEffect !== null) { - finishedWork.lastEffect.nextEffect = finishedWork; - firstEffect = finishedWork.firstEffect; - } else { - firstEffect = finishedWork; - } - } else { - // There is no effect on the root. - firstEffect = finishedWork.firstEffect; - } + } // If there are pending passive effects, schedule a callback to process them. + // Do this as early as possible, so it is queued before anything else that + // might get scheduled in the commit phase. (See #16714.) + // TODO: Delete all other places that schedule the passive effect callback + // They're redundant. - if (firstEffect !== null) { + if ( + (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || + (finishedWork.flags & PassiveMask) !== NoFlags + ) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + }); + } + } // Check if there are any effects in the whole tree. + // TODO: This is left over from the effect list implementation, where we had + // to check for the existence of `firstEffect` to satsify Flow. I think the + // only other reason this optimization exists is because it affects profiling. + // Reconsider whether this is necessary. + + var subtreeHasEffects = + (finishedWork.subtreeFlags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + var rootHasEffect = + (finishedWork.flags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + + if (subtreeHasEffects || rootHasEffect) { + var prevTransition = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority(DiscreteEventPriority); var prevExecutionContext = executionContext; - executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles + executionContext |= CommitContext; // Reset this to null before calling lifecycles ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass // of the effect list for each phase: all mutation effects come before all @@ -18852,58 +19685,18 @@ function commitRootImpl(root, renderPriorityLevel) { // state of the host tree right before we mutate it. This is where // getSnapshotBeforeUpdate is called. - focusedInstanceHandle = prepareForCommit(root.containerInfo); - shouldFireAfterActiveInstanceBlur = false; - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitBeforeMutationEffects, null); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); // We no longer need to track the active instance fiber - - focusedInstanceHandle = null; + var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects( + root, + finishedWork + ); { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); - } // The next phase is the mutation phase, where we mutate the host tree. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback( - null, - commitMutationEffects, - null, - root, - renderPriorityLevel - ); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error = clearCaughtError(); + } - captureCommitPhaseError(nextEffect, _error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); + commitMutationEffects(root, finishedWork); resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after // the mutation phase, so that the previous tree is still current during @@ -18911,38 +19704,15 @@ function commitRootImpl(root, renderPriorityLevel) { // work is current during componentDidMount/Update. root.current = finishedWork; // The next phase is the layout phase, where we call effects that read - // the host tree after it's been mutated. The idiomatic use case for this is - // layout, but class component lifecycles also fire here for legacy reasons. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error2 = clearCaughtError(); - - captureCommitPhaseError(nextEffect, _error2); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); - nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an + commitLayoutEffects(finishedWork, root, lanes); // opportunity to paint. requestPaint(); + executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value. - { - popInteractions(prevInteractions); - } - - executionContext = prevExecutionContext; + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; } else { // No effects. root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were @@ -18954,71 +19724,25 @@ function commitRootImpl(root, renderPriorityLevel) { } } - 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. rootDoesHavePassiveEffects = false; rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; - pendingPassiveEffectsRenderPriority = renderPriorityLevel; - } else { - // We are done with the effect chain at this point so let's clear the - // nextEffect pointers to assist with GC. If we have passive effects, we'll - // clear this in flushPassiveEffects. - nextEffect = firstEffect; - - while (nextEffect !== null) { - var nextNextEffect = nextEffect.nextEffect; - nextEffect.nextEffect = null; - - if (nextEffect.flags & Deletion) { - detachFiberAfterEffects(nextEffect); - } - - nextEffect = nextNextEffect; - } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root - if (remainingLanes !== NoLanes) { - { - if (spawnedWorkDuringRender !== null) { - var expirationTimes = spawnedWorkDuringRender; - spawnedWorkDuringRender = null; - - for (var i = 0; i < expirationTimes.length; i++) { - scheduleInteractions( - root, - expirationTimes[i], - root.memoizedInteractions - ); - } - } - - schedulePendingInteractions(root, remainingLanes); - } - } else { + if (remainingLanes === NoLanes) { // If there's no remaining work, we can clear the set of already failed // error boundaries. legacyErrorBoundariesThatAlreadyFailed = null; } - { - 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, lanes); - } - } - - if (remainingLanes === SyncLane) { - // Count the number of times the root synchronously re-renders without + if (includesSomeLane(remainingLanes, SyncLane)) { // finishing. If there are too many, it indicates an infinite update loop. + if (root === rootWithNestedUpdates) { nestedUpdateCount++; } else { @@ -19034,220 +19758,65 @@ function commitRootImpl(root, renderPriorityLevel) { ensureRootIsScheduled(root, now()); - if (hasUncaughtError) { - hasUncaughtError = false; - var _error3 = firstUncaughtError; - firstUncaughtError = null; - throw _error3; - } - - if ((executionContext & LegacyUnbatchedContext) !== NoContext) { - // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired - // synchronously, but layout updates should be deferred until the end - // of the batch. - - return null; - } // If layout work was scheduled, flush it now. - - flushSyncCallbackQueue(); - - return null; -} - -function commitBeforeMutationEffects() { - while (nextEffect !== null) { - var current = nextEffect.alternate; - - if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { - if ((nextEffect.flags & Deletion) !== NoFlags) { - if (doesFiberContain(nextEffect, focusedInstanceHandle)) { - shouldFireAfterActiveInstanceBlur = true; - } - } else { - // TODO: Move this out of the hot path using a dedicated effect tag. - if ( - nextEffect.tag === SuspenseComponent && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) - ) { - shouldFireAfterActiveInstanceBlur = true; - } - } - } - - var flags = nextEffect.flags; - - if ((flags & Snapshot) !== NoFlags) { - setCurrentFiber(nextEffect); - commitBeforeMutationLifeCycles(current, nextEffect); - resetCurrentFiber(); - } - - if ((flags & Passive) !== NoFlags) { - // If there are passive effects, schedule a callback to flush at - // the earliest opportunity. - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } - } - - nextEffect = nextEffect.nextEffect; - } -} - -function commitMutationEffects(root, renderPriorityLevel) { - // TODO: Should probably move the bulk of this function to commitWork. - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & ContentReset) { - commitResetTextContent(nextEffect); - } - - if (flags & Ref) { - var current = nextEffect.alternate; - - if (current !== null) { - commitDetachRef(current); - } - } // The following switch statement is only concerned about placement, - // updates, and deletions. To avoid needing to add a case for every possible - // bitmap value, we remove the secondary effects from the effect tag and - // switch on that value. - - var primaryFlags = flags & (Placement | Update | Deletion | Hydrating); - - switch (primaryFlags) { - case Placement: { - commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. - // TODO: findDOMNode doesn't rely on this any more but isMounted does - // and isMounted is deprecated anyway so we should be able to kill this. - - nextEffect.flags &= ~Placement; - break; - } - - case PlacementAndUpdate: { - // Placement - commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. - - nextEffect.flags &= ~Placement; // Update - - var _current = nextEffect.alternate; - commitWork(_current, nextEffect); - break; - } - - case Hydrating: { - nextEffect.flags &= ~Hydrating; - break; - } - - case HydratingAndUpdate: { - nextEffect.flags &= ~Hydrating; // Update - - var _current2 = nextEffect.alternate; - commitWork(_current2, nextEffect); - break; - } - - case Update: { - var _current3 = nextEffect.alternate; - commitWork(_current3, nextEffect); - break; - } - - case Deletion: { - commitDeletion(root, nextEffect); - break; - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; + if (hasUncaughtError) { + hasUncaughtError = false; + var error$1 = firstUncaughtError; + firstUncaughtError = null; + throw error$1; } -} -function commitLayoutEffects(root, committedLanes) { - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; + if ((executionContext & LegacyUnbatchedContext) !== NoContext) { + // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired + // synchronously, but layout updates should be deferred until the end + // of the batch. - if (flags & (Update | Callback)) { - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); - } + return null; + } // If the passive effects are the result of a discrete render, flush them + // synchronously at the end of the current task so that the result is + // immediately observable. Otherwise, we assume that they are not + // order-dependent and do not need to be observed by external systems, so we + // can wait until after paint. + // TODO: We can optimize this by not scheduling the callback earlier. Since we + // currently schedule the callback in multiple places, will wait until those + // are consolidated. - { - if (flags & Ref) { - commitAttachRef(nextEffect); - } - } + if ( + includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && + root.tag !== LegacyRoot + ) { + flushPassiveEffects(); + } // If layout work was scheduled, flush it now. - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } + flushSyncCallbacks(); + + return null; } function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { - var priorityLevel = - pendingPassiveEffectsRenderPriority > NormalPriority$1 - ? NormalPriority$1 - : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoPriority$1; + // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should + // probably just combine the two functions. I believe they were only separate + // in the first place because we used to wrap it with + // `Scheduler.runWithPriority`, which accepts a function. But now we track the + // priority within React itself, so we can mutate the variable directly. + if (rootWithPendingPassiveEffects !== null) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes); + var priority = lowerEventPriority(DefaultEventPriority, renderPriority); + var prevTransition = ReactCurrentBatchConfig$2.transition; + var previousPriority = getCurrentUpdatePriority(); - { - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); + try { + ReactCurrentBatchConfig$2.transition = 0; + setCurrentUpdatePriority(priority); + return flushPassiveEffectsImpl(); + } finally { + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; } } return false; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - - { - fiber.flags |= PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags |= PassiveUnmountPendingDev; - } - } - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} - -function invokePassiveEffectCreate(effect) { - var create = effect.create; - effect.destroy = create(); -} function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { @@ -19255,8 +19824,10 @@ function flushPassiveEffectsImpl() { } var root = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; - rootWithPendingPassiveEffects = null; + rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects. + // Figure out why and fix it. It's not causing any known issues (probably + // because it's only used for profiling), but it's a refactor hazard. + pendingPassiveEffectsLanes = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -19269,113 +19840,22 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called - // before ANY passive effect create functions are called. - // Otherwise effects in sibling components might interfere with each other. - // e.g. a destroy function in one component may unintentionally override a ref - // value set by a create function in another component. - // Layout effects have the same constraint. - // First pass: Destroy stale passive effects. - - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - - for (var i = 0; i < unmountEffects.length; i += 2) { - var _effect = unmountEffects[i]; - var fiber = unmountEffects[i + 1]; - var destroy = _effect.destroy; - _effect.destroy = undefined; - - { - fiber.flags &= ~PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags &= ~PassiveUnmountPendingDev; - } - } - - if (typeof destroy === "function") { - { - setCurrentFiber(fiber); - - { - invokeGuardedCallback(null, destroy, null); - } - - if (hasCaughtError()) { - if (!(fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(fiber, error); - } - - resetCurrentFiber(); - } - } - } // Second pass: Create new passive effects. - - var mountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - - for (var _i = 0; _i < mountEffects.length; _i += 2) { - var _effect2 = mountEffects[_i]; - var _fiber = mountEffects[_i + 1]; - - { - setCurrentFiber(_fiber); - - { - invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); - } - - if (hasCaughtError()) { - if (!(_fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var _error4 = clearCaughtError(); - - captureCommitPhaseError(_fiber, _error4); - } - - resetCurrentFiber(); - } - } // Note: This currently assumes there are no passive effects on the root fiber - // because the root is not part of its own effect list. - // This could change in the future. - - var effect = root.current.firstEffect; - - while (effect !== null) { - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC - - effect.nextEffect = null; - - if (effect.flags & Deletion) { - detachFiberAfterEffects(effect); - } - - effect = nextNextEffect; - } - - { - popInteractions(prevInteractions); - finishPendingInteractions(root, lanes); - } + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects { isFlushingPassiveEffects = false; } executionContext = prevExecutionContext; - flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this + flushSyncCallbacks(); // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. nestedPassiveUpdateCount = - rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; + rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; // TODO: Move to commitPassiveMountEffects + + onPostCommitRoot(root); + return true; } @@ -19412,23 +19892,26 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { if (root !== null) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, SyncLane); } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); return; } - var fiber = sourceFiber.return; + var fiber = null; + + { + fiber = sourceFiber.return; + } while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -19439,7 +19922,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$1, sourceFiber); var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); enqueueUpdate(fiber, update); var eventTime = requestEventTime(); @@ -19448,25 +19931,6 @@ function captureCommitPhaseError(sourceFiber, error) { if (root !== null) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, SyncLane); - } else { - // This component has already been unmounted. - // We can't schedule any follow up work for the root because the fiber is already unmounted, - // but we can still call the log-only boundary so the error isn't swallowed. - // - // TODO This is only a temporary bandaid for the old reconciler fork. - // We can delete this special case once the new fork is merged. - if ( - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance) - ) { - try { - instance.componentDidCatch(error, errorInfo); - } catch (errorToIgnore) { - // TODO Ignore this error? Rethrow it? - // This is kind of an edge case. - } - } } return; @@ -19475,6 +19939,22 @@ function captureCommitPhaseError(sourceFiber, error) { fiber = fiber.return; } + + { + // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning + // will fire for errors that are thrown by destroy functions inside deleted + // trees. What it should instead do is propagate the error to the parent of + // the deleted tree. In the meantime, do not add this warning to the + // allowlist; this is only for our internal use. + error( + "Internal React error: Attempted to capture a commit phase error " + + "inside a detached tree. This indicates a bug in React. Likely " + + "causes include deleting the same fiber more than once, committing an " + + "already-finished tree, or an inconsistent return pointer.\n\n" + + "Error message:\n\n%s", + error$1 + ); + } } function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; @@ -19518,7 +19998,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { } ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, pingedLanes); } function retryTimedOutBoundary(boundaryFiber, retryLane) { @@ -19527,6 +20006,8 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { // suspended it has resolved, which means at least part of the tree was // likely unblocked. Try rendering again, at a new expiration time. if (retryLane === NoLane) { + // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? retryLane = requestRetryLane(boundaryFiber); } // TODO: Special case idle priority? @@ -19536,7 +20017,6 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { if (root !== null) { markRootUpdated(root, retryLane, eventTime); ensureRootIsScheduled(root, eventTime); - schedulePendingInteractions(root, retryLane); } } function resolveRetryWakeable(boundaryFiber, wakeable) { @@ -19626,7 +20106,7 @@ function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { return; } - if (!(fiber.mode & (BlockingMode | ConcurrentMode))) { + if (!(fiber.mode & ConcurrentMode)) { return; } @@ -19646,7 +20126,7 @@ function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. - var componentName = getComponentName(fiber.type) || "ReactComponent"; + var componentName = getComponentNameFromFiber(fiber) || "ReactComponent"; if (didWarnStateUpdateForNotYetMountedComponent !== null) { if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) { @@ -19695,15 +20175,33 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } // If there are pending passive effects unmounts for this Fiber, - // we can assume that they would have prevented this update. + } - if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { - return; + if ((fiber.flags & PassiveStatic) !== NoFlags) { + var updateQueue = fiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if (effect.destroy !== undefined) { + if ((effect.tag & Passive$1) !== NoFlags$1) { + return; + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. - var componentName = getComponentName(fiber.type) || "ReactComponent"; + var componentName = getComponentNameFromFiber(fiber) || "ReactComponent"; if (didWarnStateUpdateForUnmountedComponent !== null) { if (didWarnStateUpdateForUnmountedComponent.has(componentName)) { @@ -19787,14 +20285,23 @@ var beginWork$1; invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); if (hasCaughtError()) { - var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. - // Rethrow this error instead of the original one. + var replayError = clearCaughtError(); - throw replayError; - } else { - // This branch is reachable if the render phase is impure. - throw originalError; - } + if ( + typeof replayError === "object" && + replayError !== null && + replayError._suppressLogging && + typeof originalError === "object" && + originalError !== null && + !originalError._suppressLogging + ) { + // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. + originalError._suppressLogging = true; + } + } // We always throw the original error in case the second render pass is not idempotent. + // This can happen if a memoized function or CommonJS module doesn't throw after first invokation. + + throw originalError; } }; } @@ -19818,7 +20325,7 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) { case ForwardRef: case SimpleMemoComponent: { var renderingComponentName = - (workInProgress && getComponentName(workInProgress.type)) || + (workInProgress && getComponentNameFromFiber(workInProgress)) || "Unknown"; // Dedupe by the rendering component because it's the one that needs to be fixed. var dedupeKey = renderingComponentName; @@ -19826,7 +20333,7 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) { if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) { didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey); var setStateComponentName = - getComponentName(fiber.type) || "Unknown"; + getComponentNameFromFiber(fiber) || "Unknown"; error( "Cannot update a component (`%s`) while rendering a " + @@ -19883,7 +20390,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { "act(() => ...);\n\n" + "// for react-test-renderer:\n" + // Break up imports to avoid accidentally parsing them as dependencies. "import TestRenderer fr" + - "om react-test-renderer';\n" + + "om 'react-test-renderer';\n" + "const {act} = TestRenderer;\n" + "// ...\n" + "act(() => ...);" @@ -19901,7 +20408,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { if ( - (fiber.mode & StrictMode) !== NoMode && + (fiber.mode & StrictLegacyMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { @@ -19916,7 +20423,7 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { "This ensures that you're testing the behavior the user would see " + "in the browser." + " Learn more at https://reactjs.org/link/wrap-tests-with-act", - getComponentName(fiber.type) + getComponentNameFromFiber(fiber) ); } } @@ -19945,7 +20452,7 @@ function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { "This ensures that you're testing the behavior the user would see " + "in the browser." + " Learn more at https://reactjs.org/link/wrap-tests-with-act", - getComponentName(fiber.type) + getComponentNameFromFiber(fiber) ); } finally { if (previousFiber) { @@ -19971,7 +20478,7 @@ function warnIfUnmockedScheduler(fiber) { didWarnAboutUnmockedScheduler === false && Scheduler.unstable_flushAllWithoutAsserting === undefined ) { - if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { + if (fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; error( @@ -19985,144 +20492,6 @@ function warnIfUnmockedScheduler(fiber) { } } } -} - -function computeThreadID(root, lane) { - // Interaction threads are unique per root and expiration time. - // NOTE: Intentionally unsound cast. All that matters is that it's a number - // and it represents a batch of work. Could make a helper function instead, - // but meh this is fine for now. - return lane * 1000 + root.interactionThreadID; -} - -function markSpawnedWork(lane) { - if (spawnedWorkDuringRender === null) { - spawnedWorkDuringRender = [lane]; - } else { - spawnedWorkDuringRender.push(lane); - } -} - -function scheduleInteractions(root, lane, interactions) { - if (interactions.size > 0) { - var pendingInteractionMap = root.pendingInteractionMap; - var pendingInteractions = pendingInteractionMap.get(lane); - - 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(lane, 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, lane); - subscriber.onWorkScheduled(interactions, threadID); - } - } -} - -function schedulePendingInteractions(root, lane) { - scheduleInteractions(root, lane, tracing.__interactionsRef.current); -} - -function startWorkOnPendingInteractions(root, lanes) { - // 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, - scheduledLane - ) { - if (includesSomeLane(lanes, scheduledLane)) { - 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 performConcurrentWorkOnRoot() - // 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, lanes); - - try { - subscriber.onWorkStarted(interactions, threadID); - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { - throw error; - }); - } - } - } -} - -function finishPendingInteractions(root, committedLanes) { - var remainingLanesAfterCommit = root.pendingLanes; - var subscriber; - - try { - subscriber = tracing.__subscriberRef.current; - - if (subscriber !== null && root.memoizedInteractions.size > 0) { - // FIXME: More than one lane can finish in a single commit. - var threadID = computeThreadID(root, committedLanes); - subscriber.onWorkStopped(root.memoizedInteractions, threadID); - } - } catch (error) { - // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, 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, lane) { - // 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 (!includesSomeLane(remainingLanesAfterCommit, lane)) { - pendingInteractionMap.delete(lane); - 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$1, function() { - throw error; - }); - } - } - }); - } - }); - } } // `act` testing API function shouldForceFlushFallbacksInDEV() { @@ -20133,11 +20502,6 @@ function shouldForceFlushFallbacksInDEV() { var actingUpdatesScopeDepth = 0; -function detachFiberAfterEffects(fiber) { - fiber.sibling = null; - fiber.stateNode = null; -} - var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. var failedBoundaries = null; @@ -20614,9 +20978,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.mode = mode; // Effects this.flags = NoFlags; - this.nextEffect = null; - this.firstEffect = null; - this.lastEffect = null; + this.subtreeFlags = NoFlags; + this.deletions = null; this.lanes = NoLanes; this.childLanes = NoLanes; this.alternate = null; @@ -20743,11 +21106,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.type = current.type; // We already have an alternate. // Reset the effect tag. - workInProgress.flags = NoFlags; // The effect list is no longer valid. + workInProgress.flags = NoFlags; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; { // We intentionally reset, rather than copy, actualDuration & actualStartTime. @@ -20757,8 +21119,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; } - } + } // Reset all effects except static ones. + // Static effects are not specific to a render. + workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -20815,13 +21179,10 @@ function resetWorkInProgress(workInProgress, renderLanes) { // when they should be reading from current and writing to workInProgress. // We assume pendingProps, index, key, ref, return are still untouched to // avoid doing another reconciliation. - // Reset the effect tag but keep any Placement tags, since that's something + // Reset the effect flags but keep any Placement tags, since that's something // that child fiber is setting, not the reconciliation. - workInProgress.flags &= Placement; // The effect list is no longer valid. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; var current = workInProgress.alternate; if (current === null) { @@ -20829,6 +21190,7 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = NoLanes; workInProgress.lanes = renderLanes; workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags; workInProgress.memoizedProps = null; workInProgress.memoizedState = null; workInProgress.updateQueue = null; @@ -20846,6 +21208,8 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. @@ -20872,13 +21236,19 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag) { +function createHostRootFiber( + tag, + isStrictMode, + concurrentUpdatesByDefaultOverride +) { var mode; if (tag === ConcurrentRoot) { - mode = ConcurrentMode | BlockingMode | StrictMode; - } else if (tag === BlockingRoot) { - mode = BlockingMode | StrictMode; + mode = ConcurrentMode; + + if (isStrictMode === true) { + mode |= StrictLegacyMode; + } } else { mode = NoMode; } @@ -20930,7 +21300,7 @@ function createFiberFromTypeAndProps( case REACT_STRICT_MODE_TYPE: fiberTag = Mode; - mode |= StrictMode; + mode |= StrictLegacyMode | StrictEffectsMode; break; case REACT_PROFILER_TYPE: @@ -20952,6 +21322,10 @@ function createFiberFromTypeAndProps( // eslint-disable-next-line no-fallthrough + case REACT_CACHE_TYPE: + + // eslint-disable-next-line no-fallthrough + default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -20999,7 +21373,7 @@ function createFiberFromTypeAndProps( "named imports."; } - var ownerName = owner ? getComponentName(owner.type) : null; + var ownerName = owner ? getComponentNameFromFiber(owner) : null; if (ownerName) { info += "\n\nCheck the render method of `" + ownerName + "`."; @@ -21064,14 +21438,15 @@ function createFiberFromFragment(elements, mode, lanes, key) { function createFiberFromProfiler(pendingProps, mode, lanes, key) { { if (typeof pendingProps.id !== "string") { - error('Profiler must specify an "id" as a prop'); + error( + 'Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', + typeof pendingProps.id + ); } } - var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag. - + var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); fiber.elementType = REACT_PROFILER_TYPE; - fiber.type = REACT_PROFILER_TYPE; fiber.lanes = lanes; { @@ -21085,51 +21460,25 @@ function createFiberFromProfiler(pendingProps, mode, lanes, key) { } function createFiberFromSuspense(pendingProps, mode, lanes, key) { - var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // 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; + var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); fiber.elementType = REACT_SUSPENSE_TYPE; fiber.lanes = lanes; return fiber; } function createFiberFromSuspenseList(pendingProps, mode, lanes, 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.lanes = lanes; return fiber; } function createFiberFromOffscreen(pendingProps, mode, lanes, key) { - var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); // TODO: The OffscreenComponent 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_OFFSCREEN_TYPE; - } - + var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); fiber.elementType = REACT_OFFSCREEN_TYPE; fiber.lanes = lanes; return fiber; } function createFiberFromLegacyHidden(pendingProps, mode, lanes, key) { - var fiber = createFiber(LegacyHiddenComponent, pendingProps, key, mode); // TODO: The LegacyHidden 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_LEGACY_HIDDEN_TYPE; - } - + var fiber = createFiber(LegacyHiddenComponent, pendingProps, key, mode); fiber.elementType = REACT_LEGACY_HIDDEN_TYPE; fiber.lanes = lanes; return fiber; @@ -21180,9 +21529,8 @@ function assignFiberPropertiesInDEV(target, source) { target.dependencies = source.dependencies; target.mode = source.mode; target.flags = source.flags; - target.nextEffect = source.nextEffect; - target.firstEffect = source.firstEffect; - target.lastEffect = source.lastEffect; + target.subtreeFlags = source.subtreeFlags; + target.deletions = source.deletions; target.lanes = source.lanes; target.childLanes = source.childLanes; target.alternate = source.alternate; @@ -21214,7 +21562,7 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.pendingContext = null; this.hydrate = hydrate; this.callbackNode = null; - this.callbackPriority = NoLanePriority; + this.callbackPriority = NoLane; this.eventTimes = createLaneMap(NoLanes); this.expirationTimes = createLaneMap(NoTimestamp); this.pendingLanes = NoLanes; @@ -21226,18 +21574,8 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.entangledLanes = NoLanes; this.entanglements = createLaneMap(NoLanes); - { - this.interactionThreadID = tracing.unstable_getThreadID(); - this.memoizedInteractions = new Set(); - this.pendingInteractionMap = new Map(); - } - { switch (tag) { - case BlockingRoot: - this._debugRootType = "createBlockingRoot()"; - break; - case ConcurrentRoot: this._debugRootType = "createRoot()"; break; @@ -21249,13 +21587,28 @@ function FiberRootNode(containerInfo, tag, hydrate) { } } -function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { +function createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride +) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag); + var uninitializedFiber = createHostRootFiber(tag, isStrictMode); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + + { + var _initialState = { + element: null + }; + uninitializedFiber.memoizedState = _initialState; + } + initializeUpdateQueue(uninitializedFiber); return root; } @@ -21329,8 +21682,8 @@ function findHostInstanceWithWarning(component, methodName) { return null; } - if (hostFiber.mode & StrictMode) { - var componentName = getComponentName(fiber.type) || "Component"; + if (hostFiber.mode & StrictLegacyMode) { + var componentName = getComponentNameFromFiber(fiber) || "Component"; if (!didWarnAboutFindNodeInStrictMode[componentName]) { didWarnAboutFindNodeInStrictMode[componentName] = true; @@ -21339,7 +21692,7 @@ function findHostInstanceWithWarning(component, methodName) { try { setCurrentFiber(hostFiber); - if (fiber.mode & StrictMode) { + if (fiber.mode & StrictLegacyMode) { error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + @@ -21378,8 +21731,21 @@ function findHostInstanceWithWarning(component, methodName) { } } -function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); +function createContainer( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + isStrictMode, + concurrentUpdatesByDefaultOverride +) { + return createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + isStrictMode + ); } function updateContainer(element, container, parentComponent, callback) { { @@ -21416,7 +21782,7 @@ function updateContainer(element, container, parentComponent, callback) { "triggering nested component updates from render is not allowed. " + "If necessary, trigger nested updates in componentDidUpdate.\n\n" + "Check the render method of %s.", - getComponentName(current.type) || "Unknown" + getComponentNameFromFiber(current) || "Unknown" ); } } @@ -21444,7 +21810,12 @@ function updateContainer(element, container, parentComponent, callback) { } enqueueUpdate(current$1, update); - scheduleUpdateOnFiber(current$1, lane, eventTime); + var root = scheduleUpdateOnFiber(current$1, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, current$1, lane); + } + return lane; } function getPublicRootInstance(container) { @@ -21482,10 +21853,10 @@ var setSuspenseHandler = null; { var copyWithDeleteImpl = function(obj, path, index) { var key = path[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); if (index + 1 === path.length) { - if (Array.isArray(updated)) { + if (isArray(updated)) { updated.splice(key, 1); } else { delete updated[key]; @@ -21504,14 +21875,14 @@ var setSuspenseHandler = null; var copyWithRenameImpl = function(obj, oldPath, newPath, index) { var oldKey = oldPath[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); if (index + 1 === oldPath.length) { var newKey = newPath[index]; // $FlowFixMe number or string is fine here updated[newKey] = updated[oldKey]; - if (Array.isArray(updated)) { + if (isArray(updated)) { updated.splice(oldKey, 1); } else { delete updated[oldKey]; @@ -21556,7 +21927,7 @@ var setSuspenseHandler = null; } var key = path[index]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + var updated = isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); return updated; @@ -21713,7 +22084,10 @@ function injectIntoDevTools(devToolsConfig) { scheduleRoot: scheduleRoot, setRefreshHandler: setRefreshHandler, // Enables DevTools to append owner stacks to error messages in DEV mode. - getCurrentFiber: getCurrentFiberForDevTools + getCurrentFiber: getCurrentFiberForDevTools, + // Enables DevTools to detect reconciler version rather than renderer version + // which may not match for third party renderers. + reconcilerVersion: ReactVersion }); } @@ -21784,7 +22158,7 @@ var getInspectorDataForViewAtPoint; var createHierarchy = function(fiberHierarchy) { return fiberHierarchy.map(function(fiber) { return { - name: getComponentName(fiber.type), + name: getComponentNameFromType(fiber.type), getInspectorData: function(findNodeHandle) { return { props: getHostProps(fiber), @@ -21899,23 +22273,25 @@ var getInspectorDataForViewAtPoint; } closestInstance = - internalInstanceHandle.stateNode.canonical._internalInstanceHandle; + internalInstanceHandle.stateNode.canonical._internalInstanceHandle; // Note: this is deprecated and we want to remove it ASAP. Keeping it here for React DevTools compatibility for now. + + var nativeViewTag = + internalInstanceHandle.stateNode.canonical._nativeTag; nativeFabricUIManager.measure( internalInstanceHandle.stateNode.node, function(x, y, width, height, pageX, pageY) { + var inspectorData = getInspectorDataForInstance(closestInstance); callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: pageX, - top: pageY, - width: width, - height: height - } + Object.assign({}, inspectorData, { + pointerY: locationY, + frame: { + left: pageX, + top: pageY, + width: width, + height: height }, - getInspectorDataForInstance(closestInstance) - ) + touchedViewTag: nativeViewTag + }) ); } ); @@ -21968,7 +22344,7 @@ function findHostInstance_DEPRECATED(componentOrHandle) { "never access something that requires stale data from the previous " + "render, such as refs. Move this logic to componentDidMount and " + "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" + getComponentNameFromType(owner.type) || "A component" ); } @@ -22004,7 +22380,7 @@ function findHostInstance_DEPRECATED(componentOrHandle) { if (hostInstance.canonical) { // Fabric return hostInstance.canonical; - } + } // $FlowFixMe[incompatible-return] return hostInstance; } @@ -22021,7 +22397,7 @@ function findNodeHandle(componentOrHandle) { "never access something that requires stale data from the previous " + "render, such as refs. Move this logic to componentDidMount and " + "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" + getComponentNameFromType(owner.type) || "A component" ); } @@ -22094,17 +22470,43 @@ function dispatchCommand(handle, command, args) { } } +function sendAccessibilityEvent(handle, eventType) { + if (handle._nativeTag == null) { + { + error( + "sendAccessibilityEvent was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ); + } + + return; + } + + if (handle._internalInstanceHandle) { + nativeFabricUIManager.sendAccessibilityEvent( + handle._internalInstanceHandle.stateNode.node, + eventType + ); + } else { + ReactNativePrivateInterface.legacySendAccessibilityEvent( + handle._nativeTag, + eventType + ); + } +} + function render(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, LegacyRoot, false); + root = createContainer(containerTag, LegacyRoot, false, null, false); roots.set(containerTag, root); } - updateContainer(element, root, null, callback); + updateContainer(element, root, null, callback); // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN + return getPublicRootInstance(root); } @@ -22167,6 +22569,7 @@ exports.dispatchCommand = dispatchCommand; exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; exports.findNodeHandle = findNodeHandle; exports.render = render; +exports.sendAccessibilityEvent = sendAccessibilityEvent; exports.unmountComponentAtNode = unmountComponentAtNode; exports.unmountComponentAtNodeAndRemoveContainer = unmountComponentAtNodeAndRemoveContainer; exports.unstable_batchedUpdates = batchedUpdates; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index cf61e99d065c63..94c758fce769ab 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<9a93ce433eed65e2405523253a760a3a>> + * @generated SignedSource<> */ "use strict"; @@ -62,7 +62,8 @@ function invokeGuardedCallbackAndCatchFirstError( hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } } -var getFiberCurrentPropsFromNode = null, +var isArrayImpl = Array.isArray, + getFiberCurrentPropsFromNode = null, getInstanceFromNode = null, getNodeFromInstance = null; function executeDispatch(event, listener, inst) { @@ -74,7 +75,7 @@ function executeDispatch(event, listener, inst) { function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; - if (Array.isArray(dispatchListener)) + if (isArrayImpl(dispatchListener)) throw Error("executeDirectDispatch(...): Invalid `event`."); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) @@ -335,9 +336,9 @@ function accumulate(current, next) { ); return null == current ? next - : Array.isArray(current) + : isArrayImpl(current) ? current.concat(next) - : Array.isArray(next) + : isArrayImpl(next) ? [current].concat(next) : [current, next]; } @@ -347,12 +348,12 @@ function accumulateInto(current, next) { "accumulateInto(...): Accumulated items must not be null or undefined." ); if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; + if (isArrayImpl(current)) { + if (isArrayImpl(next)) return current.push.apply(current, next), current; current.push(next); return current; } - return Array.isArray(next) ? [current].concat(next) : [current, next]; + return isArrayImpl(next) ? [current].concat(next) : [current, next]; } function forEachAccumulated(arr, cb, scope) { Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); @@ -578,7 +579,7 @@ var ResponderEventPlugin = { b: { JSCompiler_temp = shouldSetEventType._dispatchListeners; targetInst = shouldSetEventType._dispatchInstances; - if (Array.isArray(JSCompiler_temp)) + if (isArrayImpl(JSCompiler_temp)) for ( depthA = 0; depthA < JSCompiler_temp.length && @@ -929,7 +930,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_217 = { +var injectedNamesToPlugins$jscomp$inline_219 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -964,34 +965,34 @@ var injectedNamesToPlugins$jscomp$inline_217 = { } } }, - isOrderingDirty$jscomp$inline_218 = !1, - pluginName$jscomp$inline_219; -for (pluginName$jscomp$inline_219 in injectedNamesToPlugins$jscomp$inline_217) + isOrderingDirty$jscomp$inline_220 = !1, + pluginName$jscomp$inline_221; +for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) if ( - injectedNamesToPlugins$jscomp$inline_217.hasOwnProperty( - pluginName$jscomp$inline_219 + injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( + pluginName$jscomp$inline_221 ) ) { - var pluginModule$jscomp$inline_220 = - injectedNamesToPlugins$jscomp$inline_217[pluginName$jscomp$inline_219]; + var pluginModule$jscomp$inline_222 = + injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_219) || - namesToPlugins[pluginName$jscomp$inline_219] !== - pluginModule$jscomp$inline_220 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || + namesToPlugins[pluginName$jscomp$inline_221] !== + pluginModule$jscomp$inline_222 ) { - if (namesToPlugins[pluginName$jscomp$inline_219]) + if (namesToPlugins[pluginName$jscomp$inline_221]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_219 + + pluginName$jscomp$inline_221 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_219 - ] = pluginModule$jscomp$inline_220; - isOrderingDirty$jscomp$inline_218 = !0; + pluginName$jscomp$inline_221 + ] = pluginModule$jscomp$inline_222; + isOrderingDirty$jscomp$inline_220 = !0; } } -isOrderingDirty$jscomp$inline_218 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1015,7 +1016,7 @@ function executeDispatchesAndReleaseTopLevel(e) { if (e) { var dispatchListeners = e._dispatchListeners, dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) + if (isArrayImpl(dispatchListeners)) for ( var i = 0; i < dispatchListeners.length && !e.isPropagationStopped(); @@ -1207,13 +1208,18 @@ function getComponentNameFromType(type) { return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; - innerType = innerType.displayName || innerType.name || ""; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: return ( - type.displayName || - ("" !== innerType ? "ForwardRef(" + innerType + ")" : "ForwardRef") + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" ); - case REACT_MEMO_TYPE: - return getComponentNameFromType(type.type); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; @@ -1416,7 +1422,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) + if (isArrayImpl(node)) for (var i = node.length; i-- && 0 < removedKeyCount; ) restoreDeletedValuesInNestedArray( updatePayload, @@ -1462,9 +1468,9 @@ function diffNestedProperty( : prevProp ? clearNestedProperty(updatePayload, prevProp, validAttributes) : updatePayload; - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) + if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { var minLength = prevProp.length < nextProp.length ? prevProp.length : nextProp.length, i; @@ -1489,7 +1495,7 @@ function diffNestedProperty( ); return updatePayload; } - return Array.isArray(prevProp) + return isArrayImpl(prevProp) ? diffProperties( updatePayload, ReactNativePrivateInterface.flattenStyle(prevProp), @@ -1505,7 +1511,7 @@ function diffNestedProperty( } function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) return updatePayload; - if (!Array.isArray(nextProp)) + if (!isArrayImpl(nextProp)) return diffProperties( updatePayload, emptyObject, @@ -1522,7 +1528,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { } function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) return updatePayload; - if (!Array.isArray(prevProp)) + if (!isArrayImpl(prevProp)) return diffProperties( updatePayload, prevProp, @@ -1686,7 +1692,29 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(), - nextTransitionLane = 64, + scheduleCallback = Scheduler.unstable_scheduleCallback, + cancelCallback = Scheduler.unstable_cancelCallback, + shouldYield = Scheduler.unstable_shouldYield, + requestPaint = Scheduler.unstable_requestPaint, + now = Scheduler.unstable_now, + ImmediatePriority = Scheduler.unstable_ImmediatePriority, + UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + NormalPriority = Scheduler.unstable_NormalPriority, + IdlePriority = Scheduler.unstable_IdlePriority, + rendererID = null, + injectedHook = null; +function onCommitRoot(root) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + root, + void 0, + 128 === (root.current.flags & 128) + ); + } catch (err) {} +} +var nextTransitionLane = 64, nextRetryLane = 4194304; function getHighestPriorityLanes(lanes) { switch (lanes & -lanes) { @@ -1744,18 +1772,19 @@ function getNextLanes(root, wipLanes) { suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes, nonIdlePendingLanes = pendingLanes & 268435455; - 0 !== nonIdlePendingLanes - ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes), - 0 !== pendingLanes - ? (nextLanes = getHighestPriorityLanes(pendingLanes)) - : ((pingedLanes &= nonIdlePendingLanes), - 0 !== pingedLanes && - (nextLanes = getHighestPriorityLanes(pingedLanes)))) - : ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + if (0 !== nonIdlePendingLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? (nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes))); + } else + (nonIdlePendingLanes = pendingLanes & ~suspendedLanes), 0 !== nonIdlePendingLanes ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) : 0 !== pingedLanes && - (nextLanes = getHighestPriorityLanes(pingedLanes))); + (nextLanes = getHighestPriorityLanes(pingedLanes)); if (0 === nextLanes) return 0; if ( 0 !== wipLanes && @@ -1767,13 +1796,16 @@ function getNextLanes(root, wipLanes) { (16 === suspendedLanes && 0 !== (pingedLanes & 4194240))) ) return wipLanes; + 0 === (root.current.mode & 32) && + 0 !== (nextLanes & 4) && + (nextLanes |= pendingLanes & 16); wipLanes = root.entangledLanes; if (0 !== wipLanes) for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (suspendedLanes = 31 - clz32(wipLanes)), - (pingedLanes = 1 << suspendedLanes), - (nextLanes |= root[suspendedLanes]), - (wipLanes &= ~pingedLanes); + (pendingLanes = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~suspendedLanes); return nextLanes; } function computeExpirationTime(lane, currentTime) { @@ -1801,12 +1833,13 @@ function computeExpirationTime(lane, currentTime) { case 524288: case 1048576: case 2097152: + return currentTime + 5e3; case 4194304: case 8388608: case 16777216: case 33554432: case 67108864: - return currentTime + 5e3; + return -1; case 134217728: case 268435456: case 536870912: @@ -1832,16 +1865,12 @@ function markRootUpdated(root, updateLane, eventTime) { updateLane = 31 - clz32(updateLane); root[updateLane] = eventTime; } -function markRootExpired(root, expiredLanes) { - root.entanglements[0] |= expiredLanes; - root.entangledLanes |= 1; - root.pendingLanes |= 1; -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; root.suspendedLanes = 0; root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; root.mutableReadLanes &= remainingLanes; root.entangledLanes &= remainingLanes; remainingLanes = root.entanglements; @@ -1930,7 +1959,8 @@ function describeFunctionComponentFrame(fn, source) { ? describeComponentFrame(fn.displayName || fn.name || null, source, null) : ""; } -var valueStack = [], +var hasOwnProperty = Object.prototype.hasOwnProperty, + valueStack = [], index = -1; function createCursor(defaultValue) { return { current: defaultValue }; @@ -2026,31 +2056,10 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor); push(didPerformWorkStackCursor, didChange); } -var scheduleCallback = Scheduler.unstable_scheduleCallback, - cancelCallback = Scheduler.unstable_cancelCallback, - shouldYield = Scheduler.unstable_shouldYield, - requestPaint = Scheduler.unstable_requestPaint, - now = Scheduler.unstable_now, - ImmediatePriority = Scheduler.unstable_ImmediatePriority, - UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority = Scheduler.unstable_NormalPriority, - IdlePriority = Scheduler.unstable_IdlePriority, - rendererID = null, - injectedHook = null; -function onCommitRoot(root) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - root, - void 0, - 128 === (root.current.flags & 128) - ); - } catch (err) {} -} var syncQueue = null, + includesLegacySyncCallbacks = !1, isFlushingSyncQueue = !1; -function flushSyncCallbackQueue() { +function flushSyncCallbacks() { if (!isFlushingSyncQueue && null !== syncQueue) { isFlushingSyncQueue = !0; var i = 0, @@ -2063,9 +2072,10 @@ function flushSyncCallbackQueue() { while (null !== callback); } syncQueue = null; + includesLegacySyncCallbacks = !1; } catch (error) { throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), error); } finally { (currentUpdatePriority = previousUpdatePriority), @@ -2078,8 +2088,7 @@ var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, - hasOwnProperty = Object.prototype.hasOwnProperty; +var objectIs = "function" === typeof Object.is ? Object.is : is; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2390,6 +2399,7 @@ function processUpdateQueue( } } null !== pendingQueue.callback && + 0 !== pendingQueue.lane && ((workInProgress$jscomp$0.flags |= 64), (updateLane = queue.effects), null === updateLane @@ -2584,7 +2594,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && @@ -2606,7 +2615,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var isArray = Array.isArray; function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2659,15 +2667,14 @@ function coerceRef(returnFiber, current, element) { return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if ("textarea" !== returnFiber.type) - throw ((returnFiber = Object.prototype.toString.call(newChild)), - Error( - "Objects are not valid as a React child (found: " + - ("[object Object]" === returnFiber - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : returnFiber) + - "). If you meant to render a collection of children, use an array instead." - )); + returnFiber = Object.prototype.toString.call(newChild); + throw Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === returnFiber + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : returnFiber) + + "). If you meant to render a collection of children, use an array instead." + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { @@ -2829,7 +2836,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (newChild = createFiberFromFragment( newChild, @@ -2861,7 +2868,7 @@ function ChildReconciler(shouldTrackSideEffects) { ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key ? null : updateFragment(returnFiber, oldFiber, newChild, lanes, null); @@ -2900,7 +2907,7 @@ function ChildReconciler(shouldTrackSideEffects) { updatePortal(returnFiber, existingChildren, newChild, lanes) ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (existingChildren = existingChildren.get(newIdx) || null), updateFragment(returnFiber, existingChildren, newChild, lanes, null) @@ -3083,20 +3090,19 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.type === REACT_FRAGMENT_TYPE && null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); - var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) + if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; + var key = newChild.key; for ( isUnkeyedTopLevelFragment = currentFirstChild; null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - isObject = newChild.type; - if (isObject === REACT_FRAGMENT_TYPE) { + if (isUnkeyedTopLevelFragment.key === key) { + key = newChild.type; + if (key === REACT_FRAGMENT_TYPE) { if (7 === isUnkeyedTopLevelFragment.tag) { deleteRemainingChildren( returnFiber, @@ -3110,7 +3116,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; break a; } - } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + } else if (isUnkeyedTopLevelFragment.elementType === key) { deleteRemainingChildren( returnFiber, isUnkeyedTopLevelFragment.sibling @@ -3202,6 +3208,22 @@ function ChildReconciler(shouldTrackSideEffects) { } return placeSingleChild(returnFiber); } + if (isArrayImpl(newChild)) + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + if (getIteratorFn(newChild)) + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + throwOnInvalidObjectType(returnFiber, newChild); + } if ("string" === typeof newChild || "number" === typeof newChild) return ( (newChild = "" + newChild), @@ -3220,21 +3242,6 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); - if (isArray(newChild)) - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - if (getIteratorFn(newChild)) - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - isObject && throwOnInvalidObjectType(returnFiber, newChild); if ("undefined" === typeof newChild && !isUnkeyedTopLevelFragment) switch (returnFiber.tag) { case 1: @@ -3699,7 +3706,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(263168, 4, create, deps); + return mountEffectImpl(1049600, 4, create, deps); } function updateEffect(create, deps) { return updateEffectImpl(1024, 4, create, deps); @@ -3934,7 +3941,7 @@ var ContextOnlyDispatcher = { isPending = _mountState2[0]; _mountState2 = startTransition.bind(null, _mountState2[1]); mountWorkInProgressHook().memoizedState = _mountState2; - return [_mountState2, isPending]; + return [isPending, _mountState2]; }, useMutableSource: function(source, getSnapshot, subscribe) { var hook = mountWorkInProgressHook(); @@ -3983,8 +3990,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = updateReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4025,8 +4033,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = rerenderReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4692,7 +4701,7 @@ function updateSuspenseFallbackChildren( (primaryChildren.pendingProps = primaryChildProps), (workInProgress.deletions = null)) : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 262144)); + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); null !== currentFallbackChildFragment ? (fallbackChildren = createWorkInProgress( currentFallbackChildFragment, @@ -4893,14 +4902,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$62 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$62 = lastTailNode), + for (var lastTailNode$64 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$62 + null === lastTailNode$64 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$62.sibling = null); + : (lastTailNode$64.sibling = null); } } function bubbleProperties(completedWork) { @@ -4910,19 +4919,19 @@ function bubbleProperties(completedWork) { newChildLanes = 0, subtreeFlags = 0; if (didBailout) - for (var child$63 = completedWork.child; null !== child$63; ) - (newChildLanes |= child$63.lanes | child$63.childLanes), - (subtreeFlags |= child$63.subtreeFlags & 262144), - (subtreeFlags |= child$63.flags & 262144), - (child$63.return = completedWork), - (child$63 = child$63.sibling); + for (var child$65 = completedWork.child; null !== child$65; ) + (newChildLanes |= child$65.lanes | child$65.childLanes), + (subtreeFlags |= child$65.subtreeFlags & 1835008), + (subtreeFlags |= child$65.flags & 1835008), + (child$65.return = completedWork), + (child$65 = child$65.sibling); else - for (child$63 = completedWork.child; null !== child$63; ) - (newChildLanes |= child$63.lanes | child$63.childLanes), - (subtreeFlags |= child$63.subtreeFlags), - (subtreeFlags |= child$63.flags), - (child$63.return = completedWork), - (child$63 = child$63.sibling); + for (child$65 = completedWork.child; null !== child$65; ) + (newChildLanes |= child$65.lanes | child$65.childLanes), + (subtreeFlags |= child$65.subtreeFlags), + (subtreeFlags |= child$65.flags), + (child$65.return = completedWork), + (child$65 = child$65.sibling); completedWork.subtreeFlags |= subtreeFlags; completedWork.childLanes = newChildLanes; return didBailout; @@ -5124,7 +5133,7 @@ function completeWork(current, workInProgress, renderLanes) { for (newProps = workInProgress.child; null !== newProps; ) (renderLanes = newProps), (type = current), - (renderLanes.flags &= 262146), + (renderLanes.flags &= 1835010), (updatePayload = renderLanes.alternate), null === updatePayload ? ((renderLanes.childLanes = 0), @@ -5492,67 +5501,71 @@ function commitHookEffectListMount(tag, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & tag) === tag) { - var create$80 = effect.create; - effect.destroy = create$80(); + var create$82 = effect.create; + effect.destroy = create$82(); } effect = effect.next; } while (effect !== finishedWork); } } function hideOrUnhideAllChildren(finishedWork, isHidden) { - for (var node = finishedWork; ; ) { + for (var hostSubtreeRoot = null, 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 ( - ((22 !== node.tag && 23 !== node.tag) || - null === node.memoizedState || - node === finishedWork) && - null !== node.child - ) { - node.child.return = node; - node = node.child; - continue; + if (null === hostSubtreeRoot) { + hostSubtreeRoot = node; + 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) { + if (null === hostSubtreeRoot) throw Error("Not yet implemented."); + } else if ( + ((22 !== node.tag && 23 !== node.tag) || + null === node.memoizedState || + node === finishedWork) && + 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; + hostSubtreeRoot === node && (hostSubtreeRoot = null); node = node.return; } + hostSubtreeRoot === node && (hostSubtreeRoot = null); node.sibling.return = node.return; node = node.sibling; } @@ -5698,10 +5711,9 @@ function commitPlacement(finishedWork) { : insertOrAppendPlacementNode(finishedWork, parentFiber, parent); } function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - if (((node = isHost ? node.stateNode : node.stateNode.instance), before)) { + var tag = node.tag; + if (5 === tag || 6 === tag) + if (((node = node.stateNode), before)) { if ("number" === typeof parent) throw Error("Container does not support insertBefore operation"); } else @@ -5719,58 +5731,57 @@ function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { (node = node.sibling); } function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - (node = isHost ? node.stateNode : node.stateNode.instance), - before - ? ((tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - (before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [before], - [], - [], - [] - )) - : ((before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - ["number" === typeof node ? node : node._nativeTag], - [before], - [] - ))) - : ((before = "number" === typeof node ? node : node._nativeTag), - (tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - tag.push(node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [tag.length - 1], - [], - [], - [] - )) - : (tag.push(node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - [before], - [tag.length - 1], - [] - ))); + var tag = node.tag; + if (5 === tag || 6 === tag) + if (((node = node.stateNode), before)) { + tag = parent._children; + var index = tag.indexOf(node); + 0 <= index + ? (tag.splice(index, 1), + (before = tag.indexOf(before)), + tag.splice(before, 0, node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [index], + [before], + [], + [], + [] + )) + : ((before = tag.indexOf(before)), + tag.splice(before, 0, node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + ["number" === typeof node ? node : node._nativeTag], + [before], + [] + )); + } else + (before = "number" === typeof node ? node : node._nativeTag), + (tag = parent._children), + (index = tag.indexOf(node)), + 0 <= index + ? (tag.splice(index, 1), + tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [index], + [tag.length - 1], + [], + [], + [] + )) + : (tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + [before], + [tag.length - 1], + [] + )); else if (4 !== tag && ((node = node.child), null !== node)) for ( insertOrAppendPlacementNode(node, before, parent), node = node.sibling; @@ -6092,8 +6103,8 @@ function commitLayoutEffects(finishedWork) { commitUpdateQueue(firstChild, updateQueue, instance); break; case 3: - var updateQueue$81 = firstChild.updateQueue; - if (null !== updateQueue$81) { + var updateQueue$83 = firstChild.updateQueue; + if (null !== updateQueue$83) { current = null; if (null !== firstChild.child) switch (firstChild.child.tag) { @@ -6103,7 +6114,7 @@ function commitLayoutEffects(finishedWork) { case 1: current = firstChild.child.stateNode; } - commitUpdateQueue(firstChild, updateQueue$81, current); + commitUpdateQueue(firstChild, updateQueue$83, current); } break; case 5: @@ -6165,6 +6176,7 @@ function commitLayoutEffects(finishedWork) { var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -6230,7 +6242,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { 0 === executionContext && 0 === (fiber.mode & 1) && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue())) + includesLegacySyncCallbacks && flushSyncCallbacks())) : ensureRootIsScheduled(root, eventTime); return root; } @@ -6253,8 +6265,7 @@ function ensureRootIsScheduled(root, currentTime) { suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes, expirationTimes = root.expirationTimes, - lanes = root.pendingLanes, - expiredLanes = 0; + lanes = root.pendingLanes; 0 < lanes; ) { @@ -6264,10 +6275,9 @@ function ensureRootIsScheduled(root, currentTime) { if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) expirationTimes[index$6] = computeExpirationTime(lane, currentTime); - } else expirationTime <= currentTime && (expiredLanes |= lane); + } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } - 0 !== expiredLanes && markRootExpired(root, expiredLanes); suspendedLanes = getNextLanes( root, root === workInProgressRoot ? workInProgressRootRenderLanes : 0 @@ -6282,11 +6292,17 @@ function ensureRootIsScheduled(root, currentTime) { ) { null != existingCallbackNode && cancelCallback(existingCallbackNode); if (1 === currentTime) - (existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? (syncQueue = [existingCallbackNode]) - : syncQueue.push(existingCallbackNode), - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue), + 0 === root.tag + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + (includesLegacySyncCallbacks = !0), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)) + : ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), (existingCallbackNode = null); else { switch (lanesToEventPriority(suspendedLanes)) { @@ -6327,42 +6343,48 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - if (didTimeout) - return ( - markRootExpired(root, lanes), ensureRootIsScheduled(root, now()), null - ); - didTimeout = lanes; - var prevExecutionContext = executionContext; - executionContext |= 8; - var prevDispatcher = pushDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== didTimeout - ) - (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, didTimeout); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = prevExecutionContext; - null !== workInProgress - ? (didTimeout = 0) - : ((workInProgressRoot = null), - (workInProgressRootRenderLanes = 0), - (didTimeout = workInProgressRootExitStatus)); + var JSCompiler_inline_result = + 0 !== (lanes & root.expiredLanes) + ? !1 + : 0 !== (root.current.mode & 32) + ? !0 + : 0 === (lanes & 30); + if (JSCompiler_inline_result && !didTimeout) { + didTimeout = lanes; + JSCompiler_inline_result = executionContext; + executionContext |= 8; + var prevDispatcher = pushDispatcher(); + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== didTimeout + ) + (workInProgressRootRenderTargetTime = now() + 500), + prepareFreshStack(root, didTimeout); + do + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + ReactCurrentDispatcher$2.current = prevDispatcher; + executionContext = JSCompiler_inline_result; + null !== workInProgress + ? (didTimeout = 0) + : ((workInProgressRoot = null), + (workInProgressRootRenderLanes = 0), + (didTimeout = workInProgressRootExitStatus)); + } else didTimeout = renderRootSync(root, lanes); if (0 !== didTimeout) { 2 === didTimeout && ((executionContext |= 32), root.hydrate && (root.hydrate = !1), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + (JSCompiler_inline_result = getLanesToRetrySynchronouslyOnError(root)), + 0 !== JSCompiler_inline_result && + ((lanes = JSCompiler_inline_result), + (didTimeout = renderRootSync(root, JSCompiler_inline_result)))); if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6386,10 +6408,10 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; - prevExecutionContext = root.suspendedLanes; - if ((prevExecutionContext & lanes) !== lanes) { + JSCompiler_inline_result = root.suspendedLanes; + if ((JSCompiler_inline_result & lanes) !== lanes) { requestEventTime(); - root.pingedLanes |= root.suspendedLanes & prevExecutionContext; + root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result; break; } root.timeoutHandle = scheduleTimeout( @@ -6404,14 +6426,15 @@ function performConcurrentWorkOnRoot(root, didTimeout) { markRootSuspended$1(root, lanes); if ((lanes & 4194240) === lanes) break; didTimeout = root.eventTimes; - for (prevExecutionContext = -1; 0 < lanes; ) { + for (JSCompiler_inline_result = -1; 0 < lanes; ) { var index$5 = 31 - clz32(lanes); prevDispatcher = 1 << index$5; index$5 = didTimeout[index$5]; - index$5 > prevExecutionContext && (prevExecutionContext = index$5); + index$5 > JSCompiler_inline_result && + (JSCompiler_inline_result = index$5); lanes &= ~prevDispatcher; } - lanes = prevExecutionContext; + lanes = JSCompiler_inline_result; lanes = now() - lanes; lanes = (120 > lanes @@ -6464,17 +6487,16 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 24)) throw Error("Should not already be working."); flushPassiveEffects(); - var lanes; - if ((lanes = root === workInProgressRoot)) - lanes = 0 !== (root.entanglements[0] & workInProgressRootRenderLanes); - lanes = lanes ? workInProgressRootRenderLanes : getNextLanes(root, 0); + var lanes = getNextLanes(root, 0); + if (0 === (lanes & 1)) return ensureRootIsScheduled(root, now()), null; var exitStatus = renderRootSync(root, lanes); - 0 !== root.tag && - 2 === exitStatus && - ((executionContext |= 32), - root.hydrate && (root.hydrate = !1), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + if (0 !== root.tag && 2 === exitStatus) { + executionContext |= 32; + root.hydrate && (root.hydrate = !1); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + 0 !== errorRetryLanes && + ((lanes = errorRetryLanes), (exitStatus = renderRootSync(root, lanes))); + } if (1 === exitStatus) throw ((exitStatus = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6616,15 +6638,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$75 = returnFiber; + workInProgress$77 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$75.tag)) { - var nextState = workInProgress$75.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { + var nextState = workInProgress$77.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$75.memoizedProps; + var props = workInProgress$77.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6636,17 +6658,17 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$75.updateQueue; + var wakeables = workInProgress$77.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$75.updateQueue = updateQueue; + workInProgress$77.updateQueue = updateQueue; } else wakeables.add(wakeable); if ( - 0 === (workInProgress$75.mode & 1) && - workInProgress$75 !== returnFiber + 0 === (workInProgress$77.mode & 1) && + workInProgress$77 !== returnFiber ) { - workInProgress$75.flags |= 128; + workInProgress$77.flags |= 128; sourceFiber.flags |= 32768; sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) @@ -6679,12 +6701,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$75.flags |= 16384; - workInProgress$75.lanes = thrownValue; + workInProgress$77.flags |= 16384; + workInProgress$77.lanes = thrownValue; break a; } - workInProgress$75 = workInProgress$75.return; - } while (null !== workInProgress$75); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); value = Error( (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6693,47 +6715,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$75 = returnFiber; + workInProgress$77 = returnFiber; do { - switch (workInProgress$75.tag) { + switch (workInProgress$77.tag) { case 3: root = value; - workInProgress$75.flags |= 16384; + workInProgress$77.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$75.lanes |= thrownValue; - var update$76 = createRootErrorUpdate( - workInProgress$75, + workInProgress$77.lanes |= thrownValue; + var update$78 = createRootErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$75, update$76); + enqueueCapturedUpdate(workInProgress$77, update$78); break a; case 1: root = value; - var ctor = workInProgress$75.type, - instance = workInProgress$75.stateNode; + var ctor = workInProgress$77.type, + instance = workInProgress$77.stateNode; if ( - 0 === (workInProgress$75.flags & 128) && + 0 === (workInProgress$77.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$75.flags |= 16384; + workInProgress$77.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$75.lanes |= thrownValue; - var update$79 = createClassErrorUpdate( - workInProgress$75, + workInProgress$77.lanes |= thrownValue; + var update$81 = createClassErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$75, update$79); + enqueueCapturedUpdate(workInProgress$77, update$81); break a; } } - workInProgress$75 = workInProgress$75.return; - } while (null !== workInProgress$75); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6824,12 +6846,15 @@ function completeUnitOfWork(unitOfWork) { 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } function commitRoot(root) { - var previousUpdateLanePriority = currentUpdatePriority; + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig$2.transition; try { - (currentUpdatePriority = 1), + (ReactCurrentBatchConfig$2.transition = 0), + (currentUpdatePriority = 1), commitRootImpl(root, previousUpdateLanePriority); } finally { - currentUpdatePriority = previousUpdateLanePriority; + (ReactCurrentBatchConfig$2.transition = prevTransition), + (currentUpdatePriority = previousUpdateLanePriority); } return null; } @@ -6864,7 +6889,9 @@ function commitRootImpl(root, renderPriorityLevel) { })); remainingLanes = 0 !== (finishedWork.flags & 8054); if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { - remainingLanes = currentUpdatePriority; + remainingLanes = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = currentUpdatePriority; currentUpdatePriority = 1; var prevExecutionContext = executionContext; executionContext |= 16; @@ -6875,7 +6902,8 @@ function commitRootImpl(root, renderPriorityLevel) { commitLayoutEffects(finishedWork, root, lanes); requestPaint(); executionContext = prevExecutionContext; - currentUpdatePriority = remainingLanes; + currentUpdatePriority = previousPriority; + ReactCurrentBatchConfig$2.transition = remainingLanes; } else root.current = finishedWork; rootDoesHavePassiveEffects && ((rootDoesHavePassiveEffects = !1), @@ -6896,26 +6924,31 @@ function commitRootImpl(root, renderPriorityLevel) { (firstUncaughtError = null), root); if (0 !== (executionContext & 4)) return null; - flushSyncCallbackQueue(); + 0 !== (pendingPassiveEffectsLanes & 1) && + 0 !== root.tag && + flushPassiveEffects(); + flushSyncCallbacks(); return null; } function flushPassiveEffects() { - if (0 !== pendingPassiveEffectsLanes) { - var b = lanesToEventPriority(pendingPassiveEffectsLanes), + if (null !== rootWithPendingPassiveEffects) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), + prevTransition = ReactCurrentBatchConfig$2.transition, previousPriority = currentUpdatePriority; try { - currentUpdatePriority = 16 < b ? 16 : b; + ReactCurrentBatchConfig$2.transition = 0; + currentUpdatePriority = 16 > renderPriority ? 16 : renderPriority; if (null === rootWithPendingPassiveEffects) var JSCompiler_inline_result = !1; else { - var root = rootWithPendingPassiveEffects; + renderPriority = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; pendingPassiveEffectsLanes = 0; if (0 !== (executionContext & 24)) throw Error("Cannot flush passive effects while already rendering."); - b = executionContext; + var prevExecutionContext = executionContext; executionContext |= 16; - for (nextEffect = root.current; null !== nextEffect; ) { + for (nextEffect = renderPriority.current; null !== nextEffect; ) { var fiber = nextEffect, child = fiber.child; if (0 !== (nextEffect.flags & 16)) { @@ -6990,7 +7023,7 @@ function flushPassiveEffects() { nextEffect = fiber.return; } } - var finishedWork = root.current; + var finishedWork = renderPriority.current; for (nextEffect = finishedWork; null !== nextEffect; ) { child = nextEffect; var firstChild = child.child; @@ -7023,13 +7056,21 @@ function flushPassiveEffects() { nextEffect = deletions.return; } } - executionContext = b; - flushSyncCallbackQueue(); + executionContext = prevExecutionContext; + flushSyncCallbacks(); + if ( + injectedHook && + "function" === typeof injectedHook.onPostCommitFiberRoot + ) + try { + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); + } catch (err) {} JSCompiler_inline_result = !0; } return JSCompiler_inline_result; } finally { - currentUpdatePriority = previousPriority; + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$2.transition = prevTransition); } } return !1; @@ -7248,14 +7289,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? nextValue.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; - "function" === typeof getDerivedStateFromProps && - applyDerivedStateFromProps( - workInProgress, - updateLanes, - getDerivedStateFromProps, - current - ); nextValue.updater = classComponentUpdater; workInProgress.stateNode = nextValue; nextValue._reactInternals = workInProgress; @@ -7470,11 +7503,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateLanes = workInProgress.type._context; nextValue = workInProgress.pendingProps; hasContext = workInProgress.memoizedProps; - getDerivedStateFromProps = nextValue.value; + var newValue = nextValue.value; push(valueCursor, updateLanes._currentValue); - updateLanes._currentValue = getDerivedStateFromProps; + updateLanes._currentValue = newValue; if (null !== hasContext) - if (objectIs(hasContext.value, getDerivedStateFromProps)) { + if (objectIs(hasContext.value, newValue)) { if ( hasContext.children === nextValue.children && !didPerformWorkStackCursor.current @@ -7488,25 +7521,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - getDerivedStateFromProps = workInProgress.child, - null !== getDerivedStateFromProps && - (getDerivedStateFromProps.return = workInProgress); - null !== getDerivedStateFromProps; + newValue = workInProgress.child, + null !== newValue && (newValue.return = workInProgress); + null !== newValue; ) { - var list = getDerivedStateFromProps.dependencies; + var list = newValue.dependencies; if (null !== list) { - hasContext = getDerivedStateFromProps.child; + hasContext = newValue.child; for ( var dependency = list.firstContext; null !== dependency; ) { if (dependency.context === updateLanes) { - if (1 === getDerivedStateFromProps.tag) { + if (1 === newValue.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; - var updateQueue = getDerivedStateFromProps.updateQueue; + var updateQueue = newValue.updateQueue; if (null !== updateQueue) { updateQueue = updateQueue.shared; var pending = updateQueue.pending; @@ -7517,13 +7549,10 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateQueue.pending = dependency; } } - getDerivedStateFromProps.lanes |= renderLanes; - dependency = getDerivedStateFromProps.alternate; + newValue.lanes |= renderLanes; + dependency = newValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - getDerivedStateFromProps.return, - renderLanes - ); + scheduleWorkOnParentPath(newValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7531,32 +7560,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else hasContext = - 10 === getDerivedStateFromProps.tag - ? getDerivedStateFromProps.type === workInProgress.type + 10 === newValue.tag + ? newValue.type === workInProgress.type ? null - : getDerivedStateFromProps.child - : getDerivedStateFromProps.child; - if (null !== hasContext) - hasContext.return = getDerivedStateFromProps; + : newValue.child + : newValue.child; + if (null !== hasContext) hasContext.return = newValue; else - for ( - hasContext = getDerivedStateFromProps; - null !== hasContext; - - ) { + for (hasContext = newValue; null !== hasContext; ) { if (hasContext === workInProgress) { hasContext = null; break; } - getDerivedStateFromProps = hasContext.sibling; - if (null !== getDerivedStateFromProps) { - getDerivedStateFromProps.return = hasContext.return; - hasContext = getDerivedStateFromProps; + newValue = hasContext.sibling; + if (null !== newValue) { + newValue.return = hasContext.return; + hasContext = newValue; break; } hasContext = hasContext.return; } - getDerivedStateFromProps = hasContext; + newValue = hasContext; } reconcileChildren( current, @@ -7695,7 +7719,7 @@ function createWorkInProgress(current, pendingProps) { (workInProgress.flags = 0), (workInProgress.subtreeFlags = 0), (workInProgress.deletions = null)); - workInProgress.flags = current.flags & 262144; + workInProgress.flags = current.flags & 1835008; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7734,10 +7758,7 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - 1 <= - (null == pendingProps.unstable_level - ? 1 - : pendingProps.unstable_level) && (mode |= 8); + mode |= 24; break; case REACT_PROFILER_TYPE: return ( @@ -7843,7 +7864,7 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.callbackPriority = 0; this.eventTimes = createLaneMap(0); this.expirationTimes = createLaneMap(-1); - this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; + this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.expiredLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; this.entanglements = createLaneMap(0); } function createPortal(children, containerInfo, implementation) { @@ -7962,14 +7983,14 @@ batchedUpdatesImpl = function(fn, a) { (executionContext = prevExecutionContext), 0 === executionContext && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue()); + includesLegacySyncCallbacks && flushSyncCallbacks()); } }; var roots = new Map(), - devToolsConfig$jscomp$inline_984 = { + devToolsConfig$jscomp$inline_986 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.3", + version: "17.0.3-2d8d133e1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7984,11 +8005,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1234 = { - bundleType: devToolsConfig$jscomp$inline_984.bundleType, - version: devToolsConfig$jscomp$inline_984.version, - rendererPackageName: devToolsConfig$jscomp$inline_984.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_984.rendererConfig, +var internals$jscomp$inline_1243 = { + bundleType: devToolsConfig$jscomp$inline_986.bundleType, + version: devToolsConfig$jscomp$inline_986.version, + rendererPackageName: devToolsConfig$jscomp$inline_986.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_986.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8003,25 +8024,26 @@ var internals$jscomp$inline_1234 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_984.findFiberByHostInstance || + devToolsConfig$jscomp$inline_986.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, - getCurrentFiber: null + getCurrentFiber: null, + reconcilerVersion: "17.0.3-2d8d133e1" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1235 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1244 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1235.isDisabled && - hook$jscomp$inline_1235.supportsFiber + !hook$jscomp$inline_1244.isDisabled && + hook$jscomp$inline_1244.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1235.inject( - internals$jscomp$inline_1234 + (rendererID = hook$jscomp$inline_1244.inject( + internals$jscomp$inline_1243 )), - (injectedHook = hook$jscomp$inline_1235); + (injectedHook = hook$jscomp$inline_1244); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index f5ba497464b7eb..9b0da71618e1f0 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -8,7 +8,7 @@ * @nolint * @providesModule ReactNativeRenderer-prod * @preventMunge - * @generated + * @generated SignedSource<<8960cfed6037c61be089c6fd4cf802ce>> */ "use strict"; @@ -63,7 +63,8 @@ function invokeGuardedCallbackAndCatchFirstError( hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } } -var getFiberCurrentPropsFromNode = null, +var isArrayImpl = Array.isArray, + getFiberCurrentPropsFromNode = null, getInstanceFromNode = null, getNodeFromInstance = null; function executeDispatch(event, listener, inst) { @@ -75,7 +76,7 @@ function executeDispatch(event, listener, inst) { function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; - if (Array.isArray(dispatchListener)) + if (isArrayImpl(dispatchListener)) throw Error("executeDirectDispatch(...): Invalid `event`."); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) @@ -289,36 +290,46 @@ function recordTouchEnd(touch) { (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } -var ResponderTouchHistoryStore = { - recordTouchTrack: function(topLevelType, nativeEvent) { - if (isMoveish(topLevelType)) - nativeEvent.changedTouches.forEach(recordTouchMove); - else if (isStartish(topLevelType)) - nativeEvent.changedTouches.forEach(recordTouchStart), - (touchHistory.numberActiveTouches = nativeEvent.touches.length), - 1 === touchHistory.numberActiveTouches && - (touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier); - else if ( - "topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType - ) - if ( - (nativeEvent.changedTouches.forEach(recordTouchEnd), - (touchHistory.numberActiveTouches = nativeEvent.touches.length), - 1 === touchHistory.numberActiveTouches) +var instrumentationCallback, + ResponderTouchHistoryStore = { + instrument: function(callback) { + instrumentationCallback = callback; + }, + recordTouchTrack: function(topLevelType, nativeEvent) { + null != instrumentationCallback && + instrumentationCallback(topLevelType, nativeEvent); + if (isMoveish(topLevelType)) + nativeEvent.changedTouches.forEach(recordTouchMove); + else if (isStartish(topLevelType)) + nativeEvent.changedTouches.forEach(recordTouchStart), + (touchHistory.numberActiveTouches = nativeEvent.touches.length), + 1 === touchHistory.numberActiveTouches && + (touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier); + else if ( + "topTouchEnd" === topLevelType || + "topTouchCancel" === topLevelType ) - for (topLevelType = 0; topLevelType < touchBank.length; topLevelType++) - if ( - ((nativeEvent = touchBank[topLevelType]), - null != nativeEvent && nativeEvent.touchActive) - ) { - touchHistory.indexOfSingleActiveTouch = topLevelType; - break; - } - }, - touchHistory: touchHistory -}; + if ( + (nativeEvent.changedTouches.forEach(recordTouchEnd), + (touchHistory.numberActiveTouches = nativeEvent.touches.length), + 1 === touchHistory.numberActiveTouches) + ) + for ( + topLevelType = 0; + topLevelType < touchBank.length; + topLevelType++ + ) + if ( + ((nativeEvent = touchBank[topLevelType]), + null != nativeEvent && nativeEvent.touchActive) + ) { + touchHistory.indexOfSingleActiveTouch = topLevelType; + break; + } + }, + touchHistory: touchHistory + }; function accumulate(current, next) { if (null == next) throw Error( @@ -326,9 +337,9 @@ function accumulate(current, next) { ); return null == current ? next - : Array.isArray(current) + : isArrayImpl(current) ? current.concat(next) - : Array.isArray(next) + : isArrayImpl(next) ? [current].concat(next) : [current, next]; } @@ -338,12 +349,12 @@ function accumulateInto(current, next) { "accumulateInto(...): Accumulated items must not be null or undefined." ); if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; + if (isArrayImpl(current)) { + if (isArrayImpl(next)) return current.push.apply(current, next), current; current.push(next); return current; } - return Array.isArray(next) ? [current].concat(next) : [current, next]; + return isArrayImpl(next) ? [current].concat(next) : [current, next]; } function forEachAccumulated(arr, cb, scope) { Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); @@ -569,7 +580,7 @@ var ResponderEventPlugin = { b: { JSCompiler_temp = shouldSetEventType._dispatchListeners; targetInst = shouldSetEventType._dispatchInstances; - if (Array.isArray(JSCompiler_temp)) + if (isArrayImpl(JSCompiler_temp)) for ( depthA = 0; depthA < JSCompiler_temp.length && @@ -920,7 +931,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_222 = { +var injectedNamesToPlugins$jscomp$inline_219 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -955,34 +966,34 @@ var injectedNamesToPlugins$jscomp$inline_222 = { } } }, - isOrderingDirty$jscomp$inline_223 = !1, - pluginName$jscomp$inline_224; -for (pluginName$jscomp$inline_224 in injectedNamesToPlugins$jscomp$inline_222) + isOrderingDirty$jscomp$inline_220 = !1, + pluginName$jscomp$inline_221; +for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) if ( - injectedNamesToPlugins$jscomp$inline_222.hasOwnProperty( - pluginName$jscomp$inline_224 + injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( + pluginName$jscomp$inline_221 ) ) { - var pluginModule$jscomp$inline_225 = - injectedNamesToPlugins$jscomp$inline_222[pluginName$jscomp$inline_224]; + var pluginModule$jscomp$inline_222 = + injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_224) || - namesToPlugins[pluginName$jscomp$inline_224] !== - pluginModule$jscomp$inline_225 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || + namesToPlugins[pluginName$jscomp$inline_221] !== + pluginModule$jscomp$inline_222 ) { - if (namesToPlugins[pluginName$jscomp$inline_224]) + if (namesToPlugins[pluginName$jscomp$inline_221]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_224 + + pluginName$jscomp$inline_221 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_224 - ] = pluginModule$jscomp$inline_225; - isOrderingDirty$jscomp$inline_223 = !0; + pluginName$jscomp$inline_221 + ] = pluginModule$jscomp$inline_222; + isOrderingDirty$jscomp$inline_220 = !0; } } -isOrderingDirty$jscomp$inline_223 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1006,7 +1017,7 @@ function executeDispatchesAndReleaseTopLevel(e) { if (e) { var dispatchListeners = e._dispatchListeners, dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) + if (isArrayImpl(dispatchListeners)) for ( var i = 0; i < dispatchListeners.length && !e.isPropagationStopped(); @@ -1140,7 +1151,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1159,6 +1171,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1168,7 +1181,7 @@ function getIteratorFn(maybeIterable) { maybeIterable["@@iterator"]; return "function" === typeof maybeIterable ? maybeIterable : null; } -function getComponentName(type) { +function getComponentNameFromType(type) { if (null == type) return null; if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; @@ -1185,6 +1198,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1194,22 +1209,83 @@ function getComponentName(type) { return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; - innerType = innerType.displayName || innerType.name || ""; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: return ( - type.displayName || - ("" !== innerType ? "ForwardRef(" + innerType + ")" : "ForwardRef") + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" ); - case REACT_MEMO_TYPE: - return getComponentName(type.type); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; try { - return getComponentName(type(innerType)); + return getComponentNameFromType(type(innerType)); } catch (x) {} } return null; } +function getComponentNameFromFiber(fiber) { + var type = fiber.type; + switch (fiber.tag) { + case 24: + return "Cache"; + case 9: + return (type.displayName || "Context") + ".Consumer"; + case 10: + return (type._context.displayName || "Context") + ".Provider"; + case 18: + return "DehydratedFragment"; + case 11: + return ( + (fiber = type.render), + (fiber = fiber.displayName || fiber.name || ""), + type.displayName || + ("" !== fiber ? "ForwardRef(" + fiber + ")" : "ForwardRef") + ); + case 7: + return "Fragment"; + case 5: + return type; + case 4: + return "Portal"; + case 3: + return "Root"; + case 6: + return "Text"; + case 16: + return getComponentNameFromType(type); + case 23: + return "LegacyHidden"; + case 8: + return type === REACT_STRICT_MODE_TYPE ? "StrictMode" : "Mode"; + case 22: + return "Offscreen"; + case 12: + return "Profiler"; + case 21: + return "Scope"; + case 13: + return "Suspense"; + case 19: + return "SuspenseList"; + case 1: + case 0: + case 17: + case 2: + case 14: + case 15: + if ("function" === typeof type) + return type.displayName || type.name || null; + if ("string" === typeof type) return type; + } + return null; +} function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1218,7 +1294,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1306,19 +1382,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1352,7 +1423,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) + if (isArrayImpl(node)) for (var i = node.length; i-- && 0 < removedKeyCount; ) restoreDeletedValuesInNestedArray( updatePayload, @@ -1398,9 +1469,9 @@ function diffNestedProperty( : prevProp ? clearNestedProperty(updatePayload, prevProp, validAttributes) : updatePayload; - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) + if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { var minLength = prevProp.length < nextProp.length ? prevProp.length : nextProp.length, i; @@ -1425,7 +1496,7 @@ function diffNestedProperty( ); return updatePayload; } - return Array.isArray(prevProp) + return isArrayImpl(prevProp) ? diffProperties( updatePayload, ReactNativePrivateInterface.flattenStyle(prevProp), @@ -1441,7 +1512,7 @@ function diffNestedProperty( } function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) return updatePayload; - if (!Array.isArray(nextProp)) + if (!isArrayImpl(nextProp)) return diffProperties( updatePayload, emptyObject, @@ -1458,7 +1529,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { } function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) return updatePayload; - if (!Array.isArray(prevProp)) + if (!isArrayImpl(prevProp)) return diffProperties( updatePayload, prevProp, @@ -1568,60 +1639,277 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { }; } var ReactNativeFiberHostComponent = (function() { - function ReactNativeFiberHostComponent(tag, viewConfig) { - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - } - var _proto = ReactNativeFiberHostComponent.prototype; - _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; - _proto.measure = function(callback) { - ReactNativePrivateInterface.UIManager.measure( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureInWindow = function(callback) { - ReactNativePrivateInterface.UIManager.measureInWindow( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - if ("number" === typeof relativeToNativeNode) - var relativeNode = relativeToNativeNode; - else - relativeToNativeNode._nativeTag && - (relativeNode = relativeToNativeNode._nativeTag); - null != relativeNode && - ReactNativePrivateInterface.UIManager.measureLayout( + function ReactNativeFiberHostComponent(tag, viewConfig) { + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + } + var _proto = ReactNativeFiberHostComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + _proto.measure = function(callback) { + ReactNativePrivateInterface.UIManager.measure( this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - _proto.setNativeProps = function(nativeProps) { - nativeProps = diffProperties( - null, - emptyObject, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( + }; + _proto.measureInWindow = function(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - return ReactNativeFiberHostComponent; -})(); + }; + _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + this._nativeTag, + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + _proto.setNativeProps = function(nativeProps) { + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + this.viewConfig.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + this._nativeTag, + this.viewConfig.uiViewClassName, + nativeProps + ); + }; + return ReactNativeFiberHostComponent; + })(), + scheduleCallback = Scheduler.unstable_scheduleCallback, + cancelCallback = Scheduler.unstable_cancelCallback, + shouldYield = Scheduler.unstable_shouldYield, + requestPaint = Scheduler.unstable_requestPaint, + now = Scheduler.unstable_now, + ImmediatePriority = Scheduler.unstable_ImmediatePriority, + UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + NormalPriority = Scheduler.unstable_NormalPriority, + IdlePriority = Scheduler.unstable_IdlePriority, + rendererID = null, + injectedHook = null; +function onCommitRoot(root) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + root, + void 0, + 128 === (root.current.flags & 128) + ); + } catch (err) {} +} +var nextTransitionLane = 64, + nextRetryLane = 4194304; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return 1; + case 2: + return 2; + case 4: + return 4; + case 8: + return 8; + case 16: + return 16; + case 32: + return 32; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return lanes & 4194240; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return lanes & 130023424; + case 134217728: + return 134217728; + case 268435456: + return 268435456; + case 536870912: + return 536870912; + case 1073741824: + return 1073741824; + default: + return lanes; + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return 0; + var nextLanes = 0, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes, + nonIdlePendingLanes = pendingLanes & 268435455; + if (0 !== nonIdlePendingLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? (nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes))); + } else + (nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + 0 !== nonIdlePendingLanes + ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) + : 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes)); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) && + ((suspendedLanes = nextLanes & -nextLanes), + (pingedLanes = wipLanes & -wipLanes), + suspendedLanes >= pingedLanes || + (16 === suspendedLanes && 0 !== (pingedLanes & 4194240))) + ) + return wipLanes; + 0 !== (nextLanes & 4) && (nextLanes |= pendingLanes & 16); + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (pendingLanes = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function computeExpirationTime(lane, currentTime) { + switch (lane) { + case 1: + case 2: + case 4: + return currentTime + 250; + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return currentTime + 5e3; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return -1; + case 134217728: + case 268435456: + case 536870912: + case 1073741824: + return -1; + default: + return -1; + } +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$8 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$8; + remainingLanes[index$8] = 0; + eventTimes[index$8] = -1; + root[index$8] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$9 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$9; + (lane & entangledLanes) | (root[index$9] & entangledLanes) && + (root[index$9] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var currentUpdatePriority = 0; +function lanesToEventPriority(lanes) { + lanes &= -lanes; + return 1 < lanes + ? 4 < lanes + ? 0 !== (lanes & 268435455) + ? 16 + : 536870912 + : 4 + : 1; +} function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." @@ -1670,7 +1958,8 @@ function describeFunctionComponentFrame(fn, source) { ? describeComponentFrame(fn.displayName || fn.name || null, source, null) : ""; } -var valueStack = [], +var hasOwnProperty = Object.prototype.hasOwnProperty, + valueStack = [], index = -1; function createCursor(defaultValue) { return { current: defaultValue }; @@ -1724,13 +2013,13 @@ function pushTopLevelContextObject(fiber, context, didChange) { } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; - fiber = type.childContextTypes; + type = type.childContextTypes; if ("function" !== typeof instance.getChildContext) return parentContext; instance = instance.getChildContext(); for (var contextKey in instance) - if (!(contextKey in fiber)) + if (!(contextKey in type)) throw Error( - (getComponentName(type) || "Unknown") + + (getComponentNameFromFiber(fiber) || "Unknown") + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.' @@ -1766,344 +2055,79 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor); push(didPerformWorkStackCursor, didChange); } -var rendererID = null, - injectedHook = null, - Scheduler_now = Scheduler.unstable_now; -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; +var syncQueue = null, + includesLegacySyncCallbacks = !1, + isFlushingSyncQueue = !1; +function flushSyncCallbacks() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0, + previousUpdatePriority = currentUpdatePriority; + try { + var queue = syncQueue; + for (currentUpdatePriority = 1; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + syncQueue = null; + includesLegacySyncCallbacks = !1; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), + error); + } finally { + (currentUpdatePriority = previousUpdatePriority), + (isFlushingSyncQueue = !1); + } } + return null; } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +function is(x, y) { + return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); +} +var objectIs = "function" === typeof Object.is ? Object.is : is; +function shallowEqual(objA, objB) { + if (objectIs(objA, objB)) return !0; + if ( + "object" !== typeof objA || + null === objA || + "object" !== typeof objB || + null === objB + ) + return !1; + var keysA = Object.keys(objA), + keysB = Object.keys(objB); + if (keysA.length !== keysB.length) return !1; + for (keysB = 0; keysB < keysA.length; keysB++) + if ( + !hasOwnProperty.call(objB, keysA[keysB]) || + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + ) + return !1; + return !0; +} +function describeFiber(fiber) { + switch (fiber.tag) { case 5: - return 97; - case 3: + return describeComponentFrame(fiber.type, null, null); + case 16: + return describeComponentFrame("Lazy", null, null); + case 13: + return describeComponentFrame("Suspense", null, null); + case 19: + return describeComponentFrame("SuspenseList", null, null); + case 0: case 2: + case 15: + return describeFunctionComponentFrame(fiber.type, null); + case 11: + return describeFunctionComponentFrame(fiber.type.render, null); case 1: - return 95; - case 0: - return 90; + return (fiber = describeFunctionComponentFrame(fiber.type, null)), fiber; default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, - fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } -} -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; -function is(x, y) { - return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); -} -var objectIs = "function" === typeof Object.is ? Object.is : is, - hasOwnProperty = Object.prototype.hasOwnProperty; -function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; - if ( - "object" !== typeof objA || - null === objA || - "object" !== typeof objB || - null === objB - ) - return !1; - var keysA = Object.keys(objA), - keysB = Object.keys(objB); - if (keysA.length !== keysB.length) return !1; - for (keysB = 0; keysB < keysA.length; keysB++) - if ( - !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) - ) - return !1; - return !0; -} -function describeFiber(fiber) { - switch (fiber.tag) { - case 5: - return describeComponentFrame(fiber.type, null, null); - case 16: - return describeComponentFrame("Lazy", null, null); - case 13: - return describeComponentFrame("Suspense", null, null); - case 19: - return describeComponentFrame("SuspenseList", null, null); - case 0: - case 2: - case 15: - return describeFunctionComponentFrame(fiber.type, null); - case 11: - return describeFunctionComponentFrame(fiber.type.render, null); - case 1: - return (fiber = describeFunctionComponentFrame(fiber.type, null)), fiber; - default: - return ""; + return ""; } } function getStackByFiberInDevAndProd(workInProgress) { @@ -2132,14 +2156,14 @@ function resolveDefaultProps(Component, baseProps) { var valueCursor = createCursor(null), currentlyRenderingFiber = null, lastContextDependency = null, - lastContextWithAllBitsObserved = null; + lastFullyObservedContext = null; function resetContextDependencies() { - lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; + lastFullyObservedContext = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue = currentValue; + context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2159,44 +2183,41 @@ function scheduleWorkOnParentPath(parent, renderLanes) { } function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; - lastContextWithAllBitsObserved = lastContextDependency = null; + lastFullyObservedContext = lastContextDependency = null; workInProgress = workInProgress.dependencies; null !== workInProgress && null !== workInProgress.firstContext && (0 !== (workInProgress.lanes & renderLanes) && (didReceiveUpdate = !0), (workInProgress.firstContext = null)); } -function readContext(context, observedBits) { - if ( - lastContextWithAllBitsObserved !== context && - !1 !== observedBits && - 0 !== observedBits - ) { - if ("number" !== typeof observedBits || 1073741823 === observedBits) - (lastContextWithAllBitsObserved = context), (observedBits = 1073741823); - observedBits = { context: context, observedBits: observedBits, next: null }; - if (null === lastContextDependency) { +function readContext(context) { + var value = context._currentValue; + if (lastFullyObservedContext !== context) + if ( + ((context = { context: context, memoizedValue: value, next: null }), + null === lastContextDependency) + ) { if (null === currentlyRenderingFiber) throw 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; + lastContextDependency = context; currentlyRenderingFiber.dependencies = { lanes: 0, - firstContext: observedBits, + firstContext: context, responders: null }; - } else lastContextDependency = lastContextDependency.next = observedBits; - } - return context._currentValue; + } else lastContextDependency = lastContextDependency.next = context; + return value; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2222,14 +2243,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 4194240))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2298,111 +2337,111 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + 0 !== pendingQueue.lane && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2458,7 +2497,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2469,7 +2509,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2479,7 +2520,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2551,7 +2593,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && @@ -2573,7 +2614,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var isArray = Array.isArray; function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2626,25 +2666,22 @@ function coerceRef(returnFiber, current, element) { return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if ("textarea" !== returnFiber.type) - throw 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) + - "). If you meant to render a collection of children, use an array instead." - ); + returnFiber = Object.prototype.toString.call(newChild); + throw Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === returnFiber + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : returnFiber) + + "). If you meant to render a collection of children, use an array instead." + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2676,16 +2713,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2700,7 +2737,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2789,7 +2835,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (newChild = createFiberFromFragment( newChild, @@ -2814,22 +2860,14 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key ? null : updateFragment(returnFiber, oldFiber, newChild, lanes, null); @@ -2857,15 +2895,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -2876,7 +2906,7 @@ function ChildReconciler(shouldTrackSideEffects) { updatePortal(returnFiber, existingChildren, newChild, lanes) ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (existingChildren = existingChildren.get(newIdx) || null), updateFragment(returnFiber, existingChildren, newChild, lanes, null) @@ -3059,55 +3089,49 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.type === REACT_FRAGMENT_TYPE && null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); - var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) + if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; + var key = newChild.key; for ( isUnkeyedTopLevelFragment = currentFirstChild; null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + if (isUnkeyedTopLevelFragment.key === key) { + key = newChild.type; + if (key === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === key) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3183,6 +3207,22 @@ function ChildReconciler(shouldTrackSideEffects) { } return placeSingleChild(returnFiber); } + if (isArrayImpl(newChild)) + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + if (getIteratorFn(newChild)) + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + throwOnInvalidObjectType(returnFiber, newChild); + } if ("string" === typeof newChild || "number" === typeof newChild) return ( (newChild = "" + newChild), @@ -3201,21 +3241,6 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); - if (isArray(newChild)) - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - if (getIteratorFn(newChild)) - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - isObject && throwOnInvalidObjectType(returnFiber, newChild); if ("undefined" === typeof newChild && !isUnkeyedTopLevelFragment) switch (returnFiber.tag) { case 1: @@ -3223,7 +3248,7 @@ function ChildReconciler(shouldTrackSideEffects) { case 11: case 15: throw Error( - (getComponentName(returnFiber.type) || "Component") + + (getComponentNameFromFiber(returnFiber) || "Component") + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." ); } @@ -3285,7 +3310,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3437,10 +3462,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3465,22 +3491,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3520,7 +3557,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3550,25 +3587,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$13 = 31 - clz32(lanes), - lane = 1 << index$13; - entanglements[index$13] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3595,6 +3620,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3620,6 +3647,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3668,7 +3697,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3676,10 +3705,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(1049600, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3740,19 +3769,18 @@ function updateMemo(nextCreate, deps) { return nextCreate; } function startTransition(setPending, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = 1; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }); + var previousPriority = currentUpdatePriority; + currentUpdatePriority = + 0 !== previousPriority && 4 > previousPriority ? previousPriority : 4; + setPending(!0); + var prevTransition = ReactCurrentBatchConfig$1.transition; + ReactCurrentBatchConfig$1.transition = 1; + try { + setPending(!1), callback(); + } finally { + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$1.transition = prevTransition); + } } function dispatchAction(fiber, queue, action) { var eventTime = requestEventTime(), @@ -3764,33 +3792,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 4194240) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3847,6 +3897,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3888,7 +3940,7 @@ var ContextOnlyDispatcher = { isPending = _mountState2[0]; _mountState2 = startTransition.bind(null, _mountState2[1]); mountWorkInProgressHook().memoizedState = _mountState2; - return [_mountState2, isPending]; + return [isPending, _mountState2]; }, useMutableSource: function(source, getSnapshot, subscribe) { var hook = mountWorkInProgressHook(); @@ -3937,8 +3989,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = updateReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -3979,8 +4032,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = rerenderReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4022,7 +4076,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4098,14 +4152,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4122,30 +4177,39 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 1)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, current), - null - ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= nextProps; + } else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4155,7 +4219,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4180,7 +4244,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4340,7 +4404,8 @@ function updateClassComponent( oldState, newState, oldContext - )) + ) || + !1) ? (getDerivedStateFromProps || ("function" !== typeof instance.UNSAFE_componentWillUpdate && "function" !== typeof instance.componentWillUpdate) || @@ -4355,7 +4420,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4363,7 +4428,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4377,7 +4442,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4398,7 +4463,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4442,18 +4507,21 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; +} function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4470,7 +4538,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4482,9 +4552,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), + (workInProgress.lanes = 4194304), current ); renderLanes = createFiberFromOffscreen( @@ -4510,8 +4582,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4538,8 +4613,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4562,7 +4640,7 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren)) : (progressedPrimaryFragment = createFiberFromOffscreen( @@ -4595,13 +4673,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4611,26 +4690,22 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + var mode = workInProgress.mode; + current = current.child; + var currentFallbackChildFragment = current.sibling, + primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 1) && workInProgress.child !== current ? ((primaryChildren = workInProgress.child), (primaryChildren.childLanes = 0), (primaryChildren.pendingProps = primaryChildProps), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4655,8 +4730,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4666,16 +4740,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4684,9 +4756,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4709,7 +4781,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4730,8 +4802,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4753,19 +4824,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4775,25 +4838,23 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } - return null; + return workInProgress.child; } var appendAllChildren, updateHostContainer, @@ -4850,6 +4911,30 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (lastTailNode$64.sibling = null); } } +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$65 = completedWork.child; null !== child$65; ) + (newChildLanes |= child$65.lanes | child$65.childLanes), + (subtreeFlags |= child$65.subtreeFlags & 1835008), + (subtreeFlags |= child$65.flags & 1835008), + (child$65.return = completedWork), + (child$65 = child$65.sibling); + else + for (child$65 = completedWork.child; null !== child$65; ) + (newChildLanes |= child$65.lanes | child$65.childLanes), + (subtreeFlags |= child$65.subtreeFlags), + (subtreeFlags |= child$65.flags), + (child$65.return = completedWork), + (child$65 = child$65.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4863,76 +4948,80 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); else { if (!newProps) { if (null === workInProgress.stateNode) throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); + bubbleProperties(workInProgress); return null; } requiredContext(contextStackCursor$1.current); current = allocateTag(); - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); ReactNativePrivateInterface.UIManager.createView( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload ); - rootContainerInstance = new ReactNativeFiberHostComponent( + renderLanes = new ReactNativeFiberHostComponent( current, - renderLanes, + type, workInProgress ); instanceCache.set(current, workInProgress); instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 128); + appendAllChildren(renderLanes, workInProgress, !1, !1); + workInProgress.stateNode = renderLanes; + finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -4952,27 +5041,27 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "Text strings must be rendered within a component." ); - rootContainerInstance = allocateTag(); + renderLanes = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, + renderLanes, "RCTRawText", current, { text: newProps } ); - instanceCache.set(rootContainerInstance, workInProgress); - workInProgress.stateNode = rootContainerInstance; + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -4987,82 +5076,92 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } - if (newProps || rootContainerInstance) workInProgress.flags |= 4; + if (newProps || renderLanes) workInProgress.flags |= 4; + bubbleProperties(workInProgress); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderLanes = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), + (renderLanes = newProps), + (type = current), + (renderLanes.flags &= 1835010), + (updatePayload = renderLanes.alternate), null === updatePayload - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = renderLanes), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null)) - : ((rootContainerInstance.childLanes = - updatePayload.childLanes), - (rootContainerInstance.lanes = updatePayload.lanes), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = + ? ((renderLanes.childLanes = 0), + (renderLanes.lanes = type), + (renderLanes.child = null), + (renderLanes.subtreeFlags = 0), + (renderLanes.memoizedProps = null), + (renderLanes.memoizedState = null), + (renderLanes.updateQueue = null), + (renderLanes.dependencies = null), + (renderLanes.stateNode = null)) + : ((renderLanes.childLanes = updatePayload.childLanes), + (renderLanes.lanes = updatePayload.lanes), + (renderLanes.child = updatePayload.child), + (renderLanes.subtreeFlags = 0), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = + (renderLanes.memoizedState = updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (rootContainerInstance.type = updatePayload.type), - (renderLanes = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderLanes + (renderLanes.updateQueue = updatePayload.updateQueue), + (renderLanes.type = updatePayload.type), + (type = updatePayload.dependencies), + (renderLanes.dependencies = + null === type ? null : { - lanes: renderLanes.lanes, - firstContext: renderLanes.firstContext + lanes: type.lanes, + firstContext: type.firstContext })), (newProps = newProps.sibling); push( @@ -5073,78 +5172,74 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; case 22: case 23: return ( popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), null !== current && - (null !== current.memoizedState) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 1)) || + bubbleProperties(workInProgress), null ); } @@ -5159,8 +5254,8 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null; case 3: popHostContainer(); @@ -5168,11 +5263,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5180,8 +5275,8 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null ); case 19: @@ -5189,10 +5284,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5265,200 +5362,214 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$81 = finishedRoot.create; - finishedRoot.destroy = create$81(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$81 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$81; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$81 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$81, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$82 = effect.create; + effect.destroy = create$82(); } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } function hideOrUnhideAllChildren(finishedWork, isHidden) { - for (var node = finishedWork; ; ) { + for (var hostSubtreeRoot = null, 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 ( - ((22 !== node.tag && 23 !== node.tag) || - null === node.memoizedState || - node === finishedWork) && - null !== node.child - ) { - node.child.return = node; - node = node.child; - continue; + if (null === hostSubtreeRoot) { + hostSubtreeRoot = node; + 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) { + if (null === hostSubtreeRoot) throw Error("Not yet implemented."); + } else if ( + ((22 !== node.tag && 23 !== node.tag) || + null === node.memoizedState || + node === finishedWork) && + 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; + hostSubtreeRoot === node && (hostSubtreeRoot = null); node = node.return; } + hostSubtreeRoot === node && (hostSubtreeRoot = null); node.sibling.return = node.return; node = node.sibling; } } -function commitUnmount(finishedRoot, current) { +function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) try { injectedHook.onCommitFiberUnmount(rendererID, current); @@ -5475,26 +5586,24 @@ function commitUnmount(finishedRoot, current) { ) { var effect = (finishedRoot = finishedRoot.next); do { - var _effect2 = effect, - destroy = _effect2.destroy; - _effect2 = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (_effect2 & 4)) - enqueuePendingPassiveHookEffectUnmount(current, effect); - else { - _effect2 = current; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } + var _effect = effect, + destroy = _effect.destroy; + _effect = _effect.tag; + if (void 0 !== destroy && 0 !== (_effect & 2)) { + _effect = current; + var nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect, nearestMountedAncestor, error); } + } effect = effect.next; } while (effect !== finishedRoot); } break; case 1: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); finishedRoot = current.stateNode; if ("function" === typeof finishedRoot.componentWillUnmount) try { @@ -5502,26 +5611,36 @@ function commitUnmount(finishedRoot, current) { (finishedRoot.state = current.memoizedState), finishedRoot.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError( + current, + nearestMountedAncestor$jscomp$0, + unmountError + ); } break; case 5: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); break; case 4: - unmountHostComponents(finishedRoot, current); + unmountHostComponents( + finishedRoot, + current, + nearestMountedAncestor$jscomp$0 + ); } } -function detachFiberMutation(fiber) { - fiber.alternate = null; +function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; + null !== alternate && + ((fiber.alternate = null), detachFiberAfterEffects(alternate)); fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function isHostParent(fiber) { @@ -5556,7 +5675,7 @@ function commitPlacement(finishedWork) { "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); } - parentFiber.flags & 16 && (parentFiber.flags &= -17); + parentFiber.flags & 32 && (parentFiber.flags &= -33); a: b: for (parentFiber = finishedWork; ; ) { for (; null === parentFiber.sibling; ) { if (null === parentFiber.return || isHostParent(parentFiber.return)) { @@ -5591,10 +5710,9 @@ function commitPlacement(finishedWork) { : insertOrAppendPlacementNode(finishedWork, parentFiber, parent); } function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - if (((node = isHost ? node.stateNode : node.stateNode.instance), before)) { + var tag = node.tag; + if (5 === tag || 6 === tag) + if (((node = node.stateNode), before)) { if ("number" === typeof parent) throw Error("Container does not support insertBefore operation"); } else @@ -5612,58 +5730,57 @@ function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { (node = node.sibling); } function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - (node = isHost ? node.stateNode : node.stateNode.instance), - before - ? ((tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - (before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [before], - [], - [], - [] - )) - : ((before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - ["number" === typeof node ? node : node._nativeTag], - [before], - [] - ))) - : ((before = "number" === typeof node ? node : node._nativeTag), - (tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - tag.push(node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [tag.length - 1], - [], - [], - [] - )) - : (tag.push(node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - [before], - [tag.length - 1], - [] - ))); + var tag = node.tag; + if (5 === tag || 6 === tag) + if (((node = node.stateNode), before)) { + tag = parent._children; + var index = tag.indexOf(node); + 0 <= index + ? (tag.splice(index, 1), + (before = tag.indexOf(before)), + tag.splice(before, 0, node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [index], + [before], + [], + [], + [] + )) + : ((before = tag.indexOf(before)), + tag.splice(before, 0, node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + ["number" === typeof node ? node : node._nativeTag], + [before], + [] + )); + } else + (before = "number" === typeof node ? node : node._nativeTag), + (tag = parent._children), + (index = tag.indexOf(node)), + 0 <= index + ? (tag.splice(index, 1), + tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [index], + [tag.length - 1], + [], + [], + [] + )) + : (tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + [before], + [tag.length - 1], + [] + )); else if (4 !== tag && ((node = node.child), null !== node)) for ( insertOrAppendPlacementNode(node, before, parent), node = node.sibling; @@ -5672,7 +5789,11 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents(finishedRoot$jscomp$0, current) { +function unmountHostComponents( + finishedRoot$jscomp$0, + current, + nearestMountedAncestor$jscomp$0 +) { for ( var node = current, currentParentIsValid = !1, @@ -5710,12 +5831,13 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { a: for ( var finishedRoot = finishedRoot$jscomp$0, root = node, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0, node$jscomp$0 = root; ; ) if ( - (commitUnmount(finishedRoot, node$jscomp$0), + (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) ) (node$jscomp$0.child.return = node$jscomp$0), @@ -5742,18 +5864,18 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { [0] )) : ((finishedRoot = currentParent), - (node$jscomp$0 = node.stateNode), - recursivelyUncacheFiberNode(node$jscomp$0), + (nearestMountedAncestor = node.stateNode), + recursivelyUncacheFiberNode(nearestMountedAncestor), (root = finishedRoot._children), - (node$jscomp$0 = root.indexOf(node$jscomp$0)), - root.splice(node$jscomp$0, 1), + (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), + root.splice(nearestMountedAncestor, 1), ReactNativePrivateInterface.UIManager.manageChildren( finishedRoot._nativeTag, [], [], [], [], - [node$jscomp$0] + [nearestMountedAncestor] )); } else if (4 === node.tag) { if (null !== node.child) { @@ -5764,7 +5886,12 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { continue; } } else if ( - (commitUnmount(finishedRoot$jscomp$0, node), null !== node.child) + (commitUnmount( + finishedRoot$jscomp$0, + node, + nearestMountedAncestor$jscomp$0 + ), + null !== node.child) ) { node.child.return = node; node = node.child; @@ -5786,42 +5913,31 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do - 3 === (effect.tag & 3) && - ((finishedWork = effect.destroy), - (effect.destroy = void 0), - void 0 !== finishedWork && finishedWork()), - (effect = effect.next); - while (effect !== updateQueue); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 1: return; case 5: - updateQueue = finishedWork.stateNode; - if (null != updateQueue) { - effect = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : effect; + var instance = finishedWork.stateNode; + if (null != instance) { + var newProps = finishedWork.memoizedProps; + current = null !== current ? current.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && - ((finishedWork = updateQueue.viewConfig), - instanceProps.set(updateQueue._nativeTag, effect), - (effect = diffProperties( + ((finishedWork = instance.viewConfig), + instanceProps.set(instance._nativeTag, newProps), + (newProps = diffProperties( null, current, - effect, + newProps, finishedWork.validAttributes )), - null != effect && + null != newProps && ReactNativePrivateInterface.UIManager.updateView( - updateQueue._nativeTag, + instance._nativeTag, finishedWork.uiViewClassName, - effect + newProps )); } return; @@ -5877,17 +5993,189 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; +function commitMutationEffects(root, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + firstChild = nextEffect; + var deletions = firstChild.deletions; + if (null !== deletions) + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; + try { + unmountHostComponents(root, childToDelete, firstChild); + var alternate = childToDelete.alternate; + null !== alternate && (alternate.return = null); + childToDelete.return = null; + } catch (error) { + captureCommitPhaseError(childToDelete, firstChild, error); + } + } + deletions = firstChild.child; + if (0 !== (firstChild.subtreeFlags & 6454) && null !== deletions) + (deletions.return = firstChild), (nextEffect = deletions); + else + for (; null !== nextEffect; ) { + firstChild = nextEffect; + try { + var flags = firstChild.flags; + if (flags & 256) { + var current = firstChild.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + commitPlacement(firstChild); + firstChild.flags &= -3; + break; + case 6: + commitPlacement(firstChild); + firstChild.flags &= -3; + commitWork(firstChild.alternate, firstChild); + break; + case 2048: + firstChild.flags &= -2049; + break; + case 2052: + firstChild.flags &= -2049; + commitWork(firstChild.alternate, firstChild); + break; + case 4: + commitWork(firstChild.alternate, firstChild); + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + deletions = firstChild.sibling; + if (null !== deletions) { + deletions.return = firstChild.return; + nextEffect = deletions; + break; + } + nextEffect = firstChild.return; + } + } +} +function commitLayoutEffects(finishedWork) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; + try { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, firstChild); + break; + case 1: + var instance = firstChild.stateNode; + if (firstChild.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + firstChild.elementType === firstChild.type + ? current.memoizedProps + : resolveDefaultProps( + firstChild.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = firstChild.updateQueue; + null !== updateQueue && + commitUpdateQueue(firstChild, updateQueue, instance); + break; + case 3: + var updateQueue$83 = firstChild.updateQueue; + if (null !== updateQueue$83) { + current = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { + case 5: + current = firstChild.child.stateNode; + break; + case 1: + current = firstChild.child.stateNode; + } + commitUpdateQueue(firstChild, updateQueue$83, current); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (firstChild.flags & 256) { + current = void 0; + var ref = firstChild.ref; + if (null !== ref) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { + case 5: + current = instance$jscomp$0; + break; + default: + current = instance$jscomp$0; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + } + if (firstChild === fiber) { + nextEffect = null; + break; + } + current = firstChild.sibling; + if (null !== current) { + current.return = firstChild.return; + nextEffect = current; + break; + } + nextEffect = firstChild.return; + } + } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -5896,64 +6184,41 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, - pendingPassiveEffectsRenderPriority = 90, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], - rootsWithPendingDiscreteUpdates = null, + pendingPassiveEffectsLanes = 0, nestedUpdateCount = 0, rootWithNestedUpdates = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { - return 0 !== (executionContext & 48) + return 0 !== (executionContext & 24) ? now() : -1 !== currentEventTime ? currentEventTime : (currentEventTime = now()); } function requestUpdateLane(fiber) { - fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } - fiber = getCurrentPriorityLevel(); - 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) - : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); - return fiber; + if (0 === (fiber.mode & 1)) return 1; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); + fiber = currentUpdatePriority; + return 0 !== fiber ? fiber : 16; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (50 < nestedUpdateCount) @@ -5962,28 +6227,23 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { 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 = markUpdateLaneFromFiberToRoot(fiber, lane); - if (null === fiber) return null; - markRootUpdated(fiber, lane, eventTime); - fiber === workInProgressRoot && + var root = markUpdateLaneFromFiberToRoot(fiber, lane); + if (null === root) return null; + markRootUpdated(root, lane, eventTime); + root === workInProgressRoot && ((workInProgressRootUpdatedLanes |= lane), 4 === workInProgressRootExitStatus && - markRootSuspended$1(fiber, workInProgressRootRenderLanes)); - var priorityLevel = getCurrentPriorityLevel(); + markRootSuspended$1(root, workInProgressRootRenderLanes)); 1 === lane - ? 0 !== (executionContext & 8) && 0 === (executionContext & 48) - ? performSyncWorkOnRoot(fiber) - : (ensureRootIsScheduled(fiber, eventTime), + ? 0 !== (executionContext & 4) && 0 === (executionContext & 24) + ? performSyncWorkOnRoot(root) + : (ensureRootIsScheduled(root, eventTime), 0 === executionContext && + 0 === (fiber.mode & 1) && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue())) - : (0 === (executionContext & 4) || - (98 !== priorityLevel && 99 !== priorityLevel) || - (null === rootsWithPendingDiscreteUpdates - ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) - : rootsWithPendingDiscreteUpdates.add(fiber)), - ensureRootIsScheduled(fiber, eventTime)); - mostRecentlyUpdatedRoot = fiber; + includesLegacySyncCallbacks && flushSyncCallbacks())) + : ensureRootIsScheduled(root, eventTime); + return root; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6008,21 +6268,12 @@ function ensureRootIsScheduled(root, currentTime) { 0 < lanes; ) { - var index$7 = 31 - clz32(lanes), - lane = 1 << index$7, - expirationTime = expirationTimes[index$7]; + var index$6 = 31 - clz32(lanes), + lane = 1 << index$6, + expirationTime = expirationTimes[index$6]; if (-1 === expirationTime) { - if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { - expirationTime = currentTime; - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; - expirationTimes[index$7] = - 10 <= priority - ? expirationTime + 250 - : 6 <= priority - ? expirationTime + 5e3 - : -1; - } + if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) + expirationTimes[index$6] = computeExpirationTime(lane, currentTime); } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } @@ -6030,47 +6281,58 @@ function ensureRootIsScheduled(root, currentTime) { root, root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); - currentTime = return_highestLanePriority; if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode), + null !== existingCallbackNode && cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); + (root.callbackPriority = 0); + else if ( + ((currentTime = suspendedLanes & -suspendedLanes), + root.callbackPriority !== currentTime) + ) { + null != existingCallbackNode && cancelCallback(existingCallbackNode); + if (1 === currentTime) + 0 === root.tag + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + (includesLegacySyncCallbacks = !0), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)) + : ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), + (existingCallbackNode = null); + else { + switch (lanesToEventPriority(suspendedLanes)) { + case 1: + existingCallbackNode = ImmediatePriority; + break; + case 4: + existingCallbackNode = UserBlockingPriority; + break; + case 16: + existingCallbackNode = NormalPriority; + break; + case 536870912: + existingCallbackNode = IdlePriority; + break; + default: + existingCallbackNode = NormalPriority; + } + existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ); } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); root.callbackPriority = currentTime; root.callbackNode = existingCallbackNode; } } -function performConcurrentWorkOnRoot(root) { +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; - if (0 !== (executionContext & 48)) + currentEventTransitionLane = 0; + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; if (flushPassiveEffects() && root.callbackNode !== originalCallbackNode) @@ -6080,41 +6342,45 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - var exitStatus = lanes; - var prevExecutionContext = executionContext; - executionContext |= 16; - var prevDispatcher = pushDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== exitStatus - ) - (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, exitStatus); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = prevExecutionContext; - null !== workInProgress - ? (exitStatus = 0) - : ((workInProgressRoot = null), - (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && - ((executionContext |= 64), + var JSCompiler_inline_result = + 0 !== (lanes & root.expiredLanes) ? !1 : 0 === (lanes & 30); + if (JSCompiler_inline_result && !didTimeout) { + didTimeout = lanes; + JSCompiler_inline_result = executionContext; + executionContext |= 8; + var prevDispatcher = pushDispatcher(); + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== didTimeout + ) + (workInProgressRootRenderTargetTime = now() + 500), + prepareFreshStack(root, didTimeout); + do + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + ReactCurrentDispatcher$2.current = prevDispatcher; + executionContext = JSCompiler_inline_result; + null !== workInProgress + ? (didTimeout = 0) + : ((workInProgressRoot = null), + (workInProgressRootRenderLanes = 0), + (didTimeout = workInProgressRootExitStatus)); + } else didTimeout = renderRootSync(root, lanes); + if (0 !== didTimeout) { + 2 === didTimeout && + ((executionContext |= 32), root.hydrate && (root.hydrate = !1), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + (JSCompiler_inline_result = getLanesToRetrySynchronouslyOnError(root)), + 0 !== JSCompiler_inline_result && + ((lanes = JSCompiler_inline_result), + (didTimeout = renderRootSync(root, JSCompiler_inline_result)))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6122,7 +6388,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6132,20 +6398,20 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 130023424) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; - prevExecutionContext = root.suspendedLanes; - if ((prevExecutionContext & lanes) !== lanes) { + JSCompiler_inline_result = root.suspendedLanes; + if ((JSCompiler_inline_result & lanes) !== lanes) { requestEventTime(); - root.pingedLanes |= root.suspendedLanes & prevExecutionContext; + root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result; break; } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -6153,16 +6419,17 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; - for (prevExecutionContext = -1; 0 < lanes; ) { - var index$6 = 31 - clz32(lanes); - prevDispatcher = 1 << index$6; - index$6 = exitStatus[index$6]; - index$6 > prevExecutionContext && (prevExecutionContext = index$6); + if ((lanes & 4194240) === lanes) break; + didTimeout = root.eventTimes; + for (JSCompiler_inline_result = -1; 0 < lanes; ) { + var index$5 = 31 - clz32(lanes); + prevDispatcher = 1 << index$5; + index$5 = didTimeout[index$5]; + index$5 > JSCompiler_inline_result && + (JSCompiler_inline_result = index$5); lanes &= ~prevDispatcher; } - lanes = prevExecutionContext; + lanes = JSCompiler_inline_result; lanes = now() - lanes; lanes = (120 > lanes @@ -6205,33 +6472,26 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$11 = 31 - clz32(suspendedLanes), - lane = 1 << index$11; - root[index$11] = -1; + var index$7 = 31 - clz32(suspendedLanes), + lane = 1 << index$7; + root[index$7] = -1; suspendedLanes &= ~lane; } } function performSyncWorkOnRoot(root) { - if (0 !== (executionContext & 48)) + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( - root === workInProgressRoot && - 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); - 0 !== root.tag && - 2 === exitStatus && - ((executionContext |= 64), - root.hydrate && (root.hydrate = !1), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + var lanes = getNextLanes(root, 0); + if (0 === (lanes & 1)) return ensureRootIsScheduled(root, now()), null; + var exitStatus = renderRootSync(root, lanes); + if (0 !== root.tag && 2 === exitStatus) { + executionContext |= 32; + root.hydrate && (root.hydrate = !1); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + 0 !== errorRetryLanes && + ((lanes = errorRetryLanes), (exitStatus = renderRootSync(root, lanes))); + } if (1 === exitStatus) throw ((exitStatus = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6244,11 +6504,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6288,7 +6543,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6298,10 +6553,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6337,15 +6611,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6356,15 +6633,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$76 = returnFiber; + workInProgress$77 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$76.tag)) { - var nextState = workInProgress$76.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { + var nextState = workInProgress$77.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$76.memoizedProps; + var props = workInProgress$77.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6376,16 +6653,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$76.updateQueue; + var wakeables = workInProgress$77.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$76.updateQueue = updateQueue; + workInProgress$77.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$76.mode & 2)) { - workInProgress$76.flags |= 64; + if ( + 0 === (workInProgress$77.mode & 1) && + workInProgress$77 !== returnFiber + ) { + workInProgress$77.flags |= 128; sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6416,61 +6696,61 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$76.flags |= 8192; - workInProgress$76.lanes = thrownValue; + workInProgress$77.flags |= 16384; + workInProgress$77.lanes = thrownValue; break a; } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); value = Error( - (getComponentName(sourceFiber.type) || "A React component") + + (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." ); } 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$76 = returnFiber; + workInProgress$77 = returnFiber; do { - switch (workInProgress$76.tag) { + switch (workInProgress$77.tag) { case 3: root = value; - workInProgress$76.flags |= 8192; + workInProgress$77.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$77 = createRootErrorUpdate( - workInProgress$76, + workInProgress$77.lanes |= thrownValue; + var update$78 = createRootErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$77); + enqueueCapturedUpdate(workInProgress$77, update$78); break a; case 1: root = value; - var ctor = workInProgress$76.type, - instance = workInProgress$76.stateNode; + var ctor = workInProgress$77.type, + instance = workInProgress$77.stateNode; if ( - 0 === (workInProgress$76.flags & 64) && + 0 === (workInProgress$77.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$76.flags |= 8192; + workInProgress$77.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$80 = createClassErrorUpdate( - workInProgress$76, + workInProgress$77.lanes |= thrownValue; + var update$81 = createClassErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$80); + enqueueCapturedUpdate(workInProgress$77, update$81); break a; } } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6490,7 +6770,7 @@ function pushDispatcher() { } function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; - executionContext |= 16; + executionContext |= 8; var prevDispatcher = pushDispatcher(); (workInProgressRoot === root && workInProgressRootRenderLanes === lanes) || prepareFreshStack(root, lanes); @@ -6517,7 +6797,7 @@ function workLoopSync() { for (; null !== workInProgress; ) performUnitOfWork(workInProgress); } function workLoopConcurrent() { - for (; null !== workInProgress && !Scheduler_shouldYield(); ) + for (; null !== workInProgress && !shouldYield(); ) performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { @@ -6531,47 +6811,25 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - current = completeWork(current, completedWork, subtreeRenderLanes); - if (null !== current) { - workInProgress = current; - return; - } - current = completedWork; + if (0 === (completedWork.flags & 8192)) { if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) + ((current = completeWork(current, completedWork, subtreeRenderLanes)), + null !== current) ) { - for (var newChildLanes = 0, child = current.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (child = child.sibling); - current.childLanes = newChildLanes; + workInProgress = current; + return; } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6583,16 +6841,25 @@ function completeUnitOfWork(unitOfWork) { 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } function commitRoot(root) { - var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig$2.transition; + try { + (ReactCurrentBatchConfig$2.transition = 0), + (currentUpdatePriority = 1), + commitRootImpl(root, previousUpdateLanePriority); + } finally { + (ReactCurrentBatchConfig$2.transition = prevTransition), + (currentUpdatePriority = previousUpdateLanePriority); + } return null; } function commitRootImpl(root, renderPriorityLevel) { do flushPassiveEffects(); while (null !== rootWithPendingPassiveEffects); - if (0 !== (executionContext & 48)) + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork; + var finishedWork = root.finishedWork, + lanes = root.finishedLanes; if (null === finishedWork) return null; root.finishedWork = null; root.finishedLanes = 0; @@ -6601,282 +6868,207 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$12 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$12; - remainingLanes$jscomp$0[index$12] = 0; - eventTimes[index$12] = -1; - expirationTimes[index$12] = -1; - noLongerPendingLanes &= ~lane; - } - null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && - rootsWithPendingDiscreteUpdates.has(root) && - rootsWithPendingDiscreteUpdates.delete(root); + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; - executionContext |= 32; - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; - nextEffect = remainingLanes; - do - try { - for (eventTimes = root; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - break; - case 6: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - expirationTimes = nextEffect; - unmountHostComponents(eventTimes, expirationTimes); - var alternate = expirationTimes.alternate; - detachFiberMutation(expirationTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$88) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$88); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { + remainingLanes = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = currentUpdatePriority; + currentUpdatePriority = 1; + var prevExecutionContext = executionContext; + executionContext |= 16; + ReactCurrentOwner$2.current = null; + commitBeforeMutationEffects(root, finishedWork); + commitMutationEffects(root, finishedWork); root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance; - break; - default: - current = instance; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$89) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$89); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; + commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - executionContext = remainingLanes$jscomp$0; + executionContext = prevExecutionContext; + currentUpdatePriority = previousPriority; + ReactCurrentBatchConfig$2.transition = remainingLanes; } else root.current = finishedWork; - if (rootDoesHavePassiveEffects) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (renderPriorityLevel = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((flags$jscomp$0 = nextEffect), - (flags$jscomp$0.sibling = null), - (flags$jscomp$0.stateNode = null)), - (nextEffect = renderPriorityLevel); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - 1 === remainingLanes + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - void 0, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), (root = firstUncaughtError), (firstUncaughtError = null), root); - if (0 !== (executionContext & 8)) return null; - flushSyncCallbackQueue(); + if (0 !== (executionContext & 4)) return null; + 0 !== (pendingPassiveEffectsLanes & 1) && + 0 !== root.tag && + flushPassiveEffects(); + flushSyncCallbacks(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { - if (90 !== pendingPassiveEffectsRenderPriority) { - var priorityLevel = - 97 < pendingPassiveEffectsRenderPriority - ? 97 - : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = 90; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); - } - return !1; -} -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function flushPassiveEffectsImpl() { - if (null === rootWithPendingPassiveEffects) return !1; - var root = rootWithPendingPassiveEffects; - rootWithPendingPassiveEffects = null; - if (0 !== (executionContext & 48)) - throw Error("Cannot flush passive effects while already rendering."); - var prevExecutionContext = executionContext; - executionContext |= 32; - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$94 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$94.destroy; - effect$94.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); - } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$94 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; + if (null !== rootWithPendingPassiveEffects) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), + prevTransition = ReactCurrentBatchConfig$2.transition, + previousPriority = currentUpdatePriority; try { - var create$98 = effect$94.create; - effect$94.destroy = create$98(); - } catch (error$99) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$99); + ReactCurrentBatchConfig$2.transition = 0; + currentUpdatePriority = 16 > renderPriority ? 16 : renderPriority; + if (null === rootWithPendingPassiveEffects) + var JSCompiler_inline_result = !1; + else { + renderPriority = rootWithPendingPassiveEffects; + rootWithPendingPassiveEffects = null; + pendingPassiveEffectsLanes = 0; + if (0 !== (executionContext & 24)) + throw Error("Cannot flush passive effects while already rendering."); + var prevExecutionContext = executionContext; + executionContext |= 16; + for (nextEffect = renderPriority.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + var sibling = fiber$jscomp$0.sibling, + returnFiber = fiber$jscomp$0.return; + if (fiber$jscomp$0 === fiberToDelete) { + detachFiberAfterEffects(fiber$jscomp$0); + nextEffect = null; + break; + } + if (null !== sibling) { + sibling.return = returnFiber; + nextEffect = sibling; + break; + } + nextEffect = returnFiber; + } + } + } + var previousFiber = fiber.alternate; + if (null !== previousFiber) { + var detachedChild = previousFiber.child; + if (null !== detachedChild) { + previousFiber.child = null; + do { + var detachedSibling = detachedChild.sibling; + detachedChild.sibling = null; + detachedChild = detachedSibling; + } while (null !== detachedChild); + } + } + nextEffect = fiber; + } + } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + b: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + var sibling$jscomp$0 = fiber.sibling; + if (null !== sibling$jscomp$0) { + sibling$jscomp$0.return = fiber.return; + nextEffect = sibling$jscomp$0; + break b; + } + nextEffect = fiber.return; + } + } + var finishedWork = renderPriority.current; + for (nextEffect = finishedWork; null !== nextEffect; ) { + child = nextEffect; + var firstChild = child.child; + if (0 !== (child.subtreeFlags & 1040) && null !== firstChild) + (firstChild.return = child), (nextEffect = firstChild); + else + b: for (child = finishedWork; null !== nextEffect; ) { + deletions = nextEffect; + if (0 !== (deletions.flags & 1024)) + try { + switch (deletions.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, deletions); + } + } catch (error) { + captureCommitPhaseError(deletions, deletions.return, error); + } + if (deletions === child) { + nextEffect = null; + break b; + } + var sibling$jscomp$1 = deletions.sibling; + if (null !== sibling$jscomp$1) { + sibling$jscomp$1.return = deletions.return; + nextEffect = sibling$jscomp$1; + break b; + } + nextEffect = deletions.return; + } + } + executionContext = prevExecutionContext; + flushSyncCallbacks(); + if ( + injectedHook && + "function" === typeof injectedHook.onPostCommitFiberRoot + ) + try { + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); + } catch (err) {} + JSCompiler_inline_result = !0; + } + return JSCompiler_inline_result; + } finally { + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$2.transition = prevTransition); } } - for (create$98 = root.current.firstEffect; null !== create$98; ) - (root = create$98.nextEffect), - (create$98.nextEffect = null), - create$98.flags & 8 && - ((create$98.sibling = null), (create$98.stateNode = null)), - (create$98 = root); - executionContext = prevExecutionContext; - flushSyncCallbackQueue(); - return !0; + return !1; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { sourceFiber = createCapturedValue(error, sourceFiber); @@ -6888,42 +7080,50 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { (markRootUpdated(rootFiber, 1, sourceFiber), ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6935,7 +7135,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 130023424) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6947,15 +7147,11 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { null !== retryCache && retryCache.delete(wakeable); wakeable = 0; 0 === wakeable && - ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + (0 === (boundaryFiber.mode & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) - ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 130023424) && (nextRetryLane = 4194304))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6971,78 +7167,83 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateLanes; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, + if (0 === (renderLanes & updateLanes)) { + didReceiveUpdate = !1; + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer( workInProgress, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + break; + case 10: + updateLanes = workInProgress.type._context; + var nextValue = workInProgress.memoizedProps.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = nextValue; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); + return null !== workInProgress ? workInProgress.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; + case 19: + updateLanes = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; + } + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); + } + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7054,22 +7255,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7079,21 +7280,13 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; - "function" === typeof getDerivedStateFromProps && - applyDerivedStateFromProps( - workInProgress, - updateLanes, - getDerivedStateFromProps, - current - ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7105,28 +7298,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7135,7 +7328,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7144,7 +7337,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7153,8 +7346,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7162,7 +7355,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7170,32 +7363,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7206,19 +7399,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7258,16 +7450,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7304,27 +7496,15 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; - getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue); - context$jscomp$0._currentValue = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + nextValue = workInProgress.pendingProps; + hasContext = workInProgress.memoizedProps; + var newValue = nextValue.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = newValue; + if (null !== hasContext) + if (objectIs(hasContext.value, newValue)) { if ( - getDerivedStateFromProps.children === context.children && + hasContext.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7336,76 +7516,71 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + newValue = workInProgress.child, + null !== newValue && (newValue.return = workInProgress); + null !== newValue; ) { - var list = context$jscomp$0.dependencies; + var list = newValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + hasContext = newValue.child; for ( var dependency = list.firstContext; null !== dependency; ) { - if ( - dependency.context === updateLanes && - 0 !== (dependency.observedBits & hasContext) - ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (dependency.context === updateLanes) { + if (1 === newValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = newValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + newValue.lanes |= renderLanes; + dependency = newValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(newValue.return, renderLanes); list.lanes |= renderLanes; break; } dependency = dependency.next; } } else - getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + hasContext = + 10 === newValue.tag + ? newValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; - if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + : newValue.child + : newValue.child; + if (null !== hasContext) hasContext.return = newValue; else - for ( - getDerivedStateFromProps = context$jscomp$0; - null !== getDerivedStateFromProps; - - ) { - if (getDerivedStateFromProps === workInProgress) { - getDerivedStateFromProps = null; + for (hasContext = newValue; null !== hasContext; ) { + if (hasContext === workInProgress) { + hasContext = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + newValue = hasContext.sibling; + if (null !== newValue) { + newValue.return = hasContext.return; + hasContext = newValue; break; } - getDerivedStateFromProps = getDerivedStateFromProps.return; + hasContext = hasContext.return; } - context$jscomp$0 = getDerivedStateFromProps; + newValue = hasContext; } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7413,28 +7588,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), - (hasContext = workInProgress.pendingProps), - (updateLanes = hasContext.children), + (nextValue = workInProgress.type), + (updateLanes = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7452,11 +7626,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7466,8 +7640,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7499,8 +7673,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; } @@ -7538,9 +7712,9 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null)); + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null)); + workInProgress.flags = current.flags & 1835008; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7575,24 +7749,22 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 4; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + mode |= 24; break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 2)), (type.elementType = REACT_PROFILER_TYPE), - (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), type ); case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.lanes = lanes), type @@ -7770,7 +7942,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7805,14 +7978,14 @@ batchedUpdatesImpl = function(fn, a) { (executionContext = prevExecutionContext), 0 === executionContext && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue()); + includesLegacySyncCallbacks && flushSyncCallbacks()); } }; var roots = new Map(), - devToolsConfig$jscomp$inline_908 = { + devToolsConfig$jscomp$inline_986 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.3-experimental-2d8d133e1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7827,11 +8000,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1115 = { - bundleType: devToolsConfig$jscomp$inline_908.bundleType, - version: devToolsConfig$jscomp$inline_908.version, - rendererPackageName: devToolsConfig$jscomp$inline_908.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_908.rendererConfig, +var internals$jscomp$inline_1243 = { + bundleType: devToolsConfig$jscomp$inline_986.bundleType, + version: devToolsConfig$jscomp$inline_986.version, + rendererPackageName: devToolsConfig$jscomp$inline_986.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_986.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7846,25 +8019,26 @@ var internals$jscomp$inline_1115 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_908.findFiberByHostInstance || + devToolsConfig$jscomp$inline_986.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, - getCurrentFiber: null + getCurrentFiber: null, + reconcilerVersion: "17.0.3-experimental-2d8d133e1" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1116 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1244 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1116.isDisabled && - hook$jscomp$inline_1116.supportsFiber + !hook$jscomp$inline_1244.isDisabled && + hook$jscomp$inline_1244.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1116.inject( - internals$jscomp$inline_1115 + (rendererID = hook$jscomp$inline_1244.inject( + internals$jscomp$inline_1243 )), - (injectedHook = hook$jscomp$inline_1116); + (injectedHook = hook$jscomp$inline_1244); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -7913,10 +8087,11 @@ exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = createFiber(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); + var JSCompiler_inline_result = createFiber(3, null, null, 0); + root.current = JSCompiler_inline_result; + JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; + initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } updateContainer(element, root, null, callback); @@ -7931,6 +8106,18 @@ exports.render = function(element, containerTag, callback) { else element = null; return element; }; +exports.sendAccessibilityEvent = function(handle, eventType) { + null != handle._nativeTag && + (handle._internalInstanceHandle + ? nativeFabricUIManager.sendAccessibilityEvent( + handle._internalInstanceHandle.stateNode.node, + eventType + ) + : ReactNativePrivateInterface.legacySendAccessibilityEvent( + handle._nativeTag, + eventType + )); +}; exports.unmountComponentAtNode = unmountComponentAtNode; exports.unmountComponentAtNodeAndRemoveContainer = function(containerTag) { unmountComponentAtNode(containerTag); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index d46043b8138766..04b71971de1b90 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -7,15 +7,14 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<1a7d2241ef385ad3a6cbcb1476a22147>> + * @generated SignedSource<<3b76b5ccdbbb286322dca9906d61c805>> */ "use strict"; require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), - Scheduler = require("scheduler"), - tracing = require("scheduler/tracing"); + Scheduler = require("scheduler"); function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -63,7 +62,8 @@ function invokeGuardedCallbackAndCatchFirstError( hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } } -var getFiberCurrentPropsFromNode = null, +var isArrayImpl = Array.isArray, + getFiberCurrentPropsFromNode = null, getInstanceFromNode = null, getNodeFromInstance = null; function executeDispatch(event, listener, inst) { @@ -75,7 +75,7 @@ function executeDispatch(event, listener, inst) { function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; - if (Array.isArray(dispatchListener)) + if (isArrayImpl(dispatchListener)) throw Error("executeDirectDispatch(...): Invalid `event`."); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) @@ -336,9 +336,9 @@ function accumulate(current, next) { ); return null == current ? next - : Array.isArray(current) + : isArrayImpl(current) ? current.concat(next) - : Array.isArray(next) + : isArrayImpl(next) ? [current].concat(next) : [current, next]; } @@ -348,12 +348,12 @@ function accumulateInto(current, next) { "accumulateInto(...): Accumulated items must not be null or undefined." ); if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; + if (isArrayImpl(current)) { + if (isArrayImpl(next)) return current.push.apply(current, next), current; current.push(next); return current; } - return Array.isArray(next) ? [current].concat(next) : [current, next]; + return isArrayImpl(next) ? [current].concat(next) : [current, next]; } function forEachAccumulated(arr, cb, scope) { Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); @@ -579,7 +579,7 @@ var ResponderEventPlugin = { b: { JSCompiler_temp = shouldSetEventType._dispatchListeners; targetInst = shouldSetEventType._dispatchInstances; - if (Array.isArray(JSCompiler_temp)) + if (isArrayImpl(JSCompiler_temp)) for ( depthA = 0; depthA < JSCompiler_temp.length && @@ -930,7 +930,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_223 = { +var injectedNamesToPlugins$jscomp$inline_224 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -965,34 +965,34 @@ var injectedNamesToPlugins$jscomp$inline_223 = { } } }, - isOrderingDirty$jscomp$inline_224 = !1, - pluginName$jscomp$inline_225; -for (pluginName$jscomp$inline_225 in injectedNamesToPlugins$jscomp$inline_223) + isOrderingDirty$jscomp$inline_225 = !1, + pluginName$jscomp$inline_226; +for (pluginName$jscomp$inline_226 in injectedNamesToPlugins$jscomp$inline_224) if ( - injectedNamesToPlugins$jscomp$inline_223.hasOwnProperty( - pluginName$jscomp$inline_225 + injectedNamesToPlugins$jscomp$inline_224.hasOwnProperty( + pluginName$jscomp$inline_226 ) ) { - var pluginModule$jscomp$inline_226 = - injectedNamesToPlugins$jscomp$inline_223[pluginName$jscomp$inline_225]; + var pluginModule$jscomp$inline_227 = + injectedNamesToPlugins$jscomp$inline_224[pluginName$jscomp$inline_226]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_225) || - namesToPlugins[pluginName$jscomp$inline_225] !== - pluginModule$jscomp$inline_226 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_226) || + namesToPlugins[pluginName$jscomp$inline_226] !== + pluginModule$jscomp$inline_227 ) { - if (namesToPlugins[pluginName$jscomp$inline_225]) + if (namesToPlugins[pluginName$jscomp$inline_226]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_225 + + pluginName$jscomp$inline_226 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_225 - ] = pluginModule$jscomp$inline_226; - isOrderingDirty$jscomp$inline_224 = !0; + pluginName$jscomp$inline_226 + ] = pluginModule$jscomp$inline_227; + isOrderingDirty$jscomp$inline_225 = !0; } } -isOrderingDirty$jscomp$inline_224 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_225 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1016,7 +1016,7 @@ function executeDispatchesAndReleaseTopLevel(e) { if (e) { var dispatchListeners = e._dispatchListeners, dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) + if (isArrayImpl(dispatchListeners)) for ( var i = 0; i < dispatchListeners.length && !e.isPropagationStopped(); @@ -1208,13 +1208,18 @@ function getComponentNameFromType(type) { return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; - innerType = innerType.displayName || innerType.name || ""; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: return ( - type.displayName || - ("" !== innerType ? "ForwardRef(" + innerType + ")" : "ForwardRef") + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" ); - case REACT_MEMO_TYPE: - return getComponentNameFromType(type.type); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; @@ -1417,7 +1422,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) + if (isArrayImpl(node)) for (var i = node.length; i-- && 0 < removedKeyCount; ) restoreDeletedValuesInNestedArray( updatePayload, @@ -1463,9 +1468,9 @@ function diffNestedProperty( : prevProp ? clearNestedProperty(updatePayload, prevProp, validAttributes) : updatePayload; - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) + if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { var minLength = prevProp.length < nextProp.length ? prevProp.length : nextProp.length, i; @@ -1490,7 +1495,7 @@ function diffNestedProperty( ); return updatePayload; } - return Array.isArray(prevProp) + return isArrayImpl(prevProp) ? diffProperties( updatePayload, ReactNativePrivateInterface.flattenStyle(prevProp), @@ -1506,7 +1511,7 @@ function diffNestedProperty( } function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) return updatePayload; - if (!Array.isArray(nextProp)) + if (!isArrayImpl(nextProp)) return diffProperties( updatePayload, emptyObject, @@ -1523,7 +1528,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { } function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) return updatePayload; - if (!Array.isArray(prevProp)) + if (!isArrayImpl(prevProp)) return diffProperties( updatePayload, prevProp, @@ -1687,7 +1692,47 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(), - nextTransitionLane = 64, + scheduleCallback = Scheduler.unstable_scheduleCallback, + cancelCallback = Scheduler.unstable_cancelCallback, + shouldYield = Scheduler.unstable_shouldYield, + requestPaint = Scheduler.unstable_requestPaint, + now = Scheduler.unstable_now, + ImmediatePriority = Scheduler.unstable_ImmediatePriority, + UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + NormalPriority = Scheduler.unstable_NormalPriority, + IdlePriority = Scheduler.unstable_IdlePriority, + rendererID = null, + injectedHook = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function onCommitRoot(root, eventPriority) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + var didError = 128 === (root.current.flags & 128); + switch (eventPriority) { + case 1: + var schedulerPriority = ImmediatePriority; + break; + case 4: + schedulerPriority = UserBlockingPriority; + break; + case 16: + schedulerPriority = NormalPriority; + break; + case 536870912: + schedulerPriority = IdlePriority; + break; + default: + schedulerPriority = NormalPriority; + } + injectedHook.onCommitFiberRoot( + rendererID, + root, + schedulerPriority, + didError + ); + } catch (err) {} +} +var nextTransitionLane = 64, nextRetryLane = 4194304; function getHighestPriorityLanes(lanes) { switch (lanes & -lanes) { @@ -1745,18 +1790,19 @@ function getNextLanes(root, wipLanes) { suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes, nonIdlePendingLanes = pendingLanes & 268435455; - 0 !== nonIdlePendingLanes - ? ((pendingLanes = nonIdlePendingLanes & ~suspendedLanes), - 0 !== pendingLanes - ? (nextLanes = getHighestPriorityLanes(pendingLanes)) - : ((pingedLanes &= nonIdlePendingLanes), - 0 !== pingedLanes && - (nextLanes = getHighestPriorityLanes(pingedLanes)))) - : ((nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + if (0 !== nonIdlePendingLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? (nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes))); + } else + (nonIdlePendingLanes = pendingLanes & ~suspendedLanes), 0 !== nonIdlePendingLanes ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) : 0 !== pingedLanes && - (nextLanes = getHighestPriorityLanes(pingedLanes))); + (nextLanes = getHighestPriorityLanes(pingedLanes)); if (0 === nextLanes) return 0; if ( 0 !== wipLanes && @@ -1768,13 +1814,16 @@ function getNextLanes(root, wipLanes) { (16 === suspendedLanes && 0 !== (pingedLanes & 4194240))) ) return wipLanes; + 0 === (root.current.mode & 32) && + 0 !== (nextLanes & 4) && + (nextLanes |= pendingLanes & 16); wipLanes = root.entangledLanes; if (0 !== wipLanes) for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (suspendedLanes = 31 - clz32(wipLanes)), - (pingedLanes = 1 << suspendedLanes), - (nextLanes |= root[suspendedLanes]), - (wipLanes &= ~pingedLanes); + (pendingLanes = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~suspendedLanes); return nextLanes; } function computeExpirationTime(lane, currentTime) { @@ -1802,12 +1851,13 @@ function computeExpirationTime(lane, currentTime) { case 524288: case 1048576: case 2097152: + return currentTime + 5e3; case 4194304: case 8388608: case 16777216: case 33554432: case 67108864: - return currentTime + 5e3; + return -1; case 134217728: case 268435456: case 536870912: @@ -1833,16 +1883,12 @@ function markRootUpdated(root, updateLane, eventTime) { updateLane = 31 - clz32(updateLane); root[updateLane] = eventTime; } -function markRootExpired(root, expiredLanes) { - root.entanglements[0] |= expiredLanes; - root.entangledLanes |= 1; - root.pendingLanes |= 1; -} function markRootFinished(root, remainingLanes) { var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; root.pendingLanes = remainingLanes; root.suspendedLanes = 0; root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; root.mutableReadLanes &= remainingLanes; root.entangledLanes &= remainingLanes; remainingLanes = root.entanglements; @@ -1931,7 +1977,8 @@ function describeFunctionComponentFrame(fn, source) { ? describeComponentFrame(fn.displayName || fn.name || null, source, null) : ""; } -var valueStack = [], +var hasOwnProperty = Object.prototype.hasOwnProperty, + valueStack = [], index = -1; function createCursor(defaultValue) { return { current: defaultValue }; @@ -2027,56 +2074,10 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor); push(didPerformWorkStackCursor, didChange); } -var scheduleCallback = Scheduler.unstable_scheduleCallback, - cancelCallback = Scheduler.unstable_cancelCallback, - shouldYield = Scheduler.unstable_shouldYield, - requestPaint = Scheduler.unstable_requestPaint, - now = Scheduler.unstable_now, - ImmediatePriority = Scheduler.unstable_ImmediatePriority, - UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - NormalPriority = Scheduler.unstable_NormalPriority, - IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var rendererID = null, - injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; -function onCommitRoot(root, eventPriority) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - var didError = 128 === (root.current.flags & 128); - switch (eventPriority) { - case 1: - var schedulerPriority = ImmediatePriority; - break; - case 4: - schedulerPriority = UserBlockingPriority; - break; - case 16: - schedulerPriority = NormalPriority; - break; - case 536870912: - schedulerPriority = IdlePriority; - break; - default: - schedulerPriority = NormalPriority; - } - injectedHook.onCommitFiberRoot( - rendererID, - root, - schedulerPriority, - didError - ); - } catch (err) {} -} var syncQueue = null, + includesLegacySyncCallbacks = !1, isFlushingSyncQueue = !1; -function flushSyncCallbackQueue() { +function flushSyncCallbacks() { if (!isFlushingSyncQueue && null !== syncQueue) { isFlushingSyncQueue = !0; var i = 0, @@ -2089,9 +2090,10 @@ function flushSyncCallbackQueue() { while (null !== callback); } syncQueue = null; + includesLegacySyncCallbacks = !1; } catch (error) { throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), error); } finally { (currentUpdatePriority = previousUpdatePriority), @@ -2104,8 +2106,7 @@ var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, - hasOwnProperty = Object.prototype.hasOwnProperty; +var objectIs = "function" === typeof Object.is ? Object.is : is; function shallowEqual(objA, objB) { if (objectIs(objA, objB)) return !0; if ( @@ -2416,6 +2417,7 @@ function processUpdateQueue( } } null !== pendingQueue.callback && + 0 !== pendingQueue.lane && ((workInProgress$jscomp$0.flags |= 64), (updateLane = queue.effects), null === updateLane @@ -2610,7 +2612,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && @@ -2632,7 +2633,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var isArray = Array.isArray; function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2685,15 +2685,14 @@ function coerceRef(returnFiber, current, element) { return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if ("textarea" !== returnFiber.type) - throw ((returnFiber = Object.prototype.toString.call(newChild)), - Error( - "Objects are not valid as a React child (found: " + - ("[object Object]" === returnFiber - ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : returnFiber) + - "). If you meant to render a collection of children, use an array instead." - )); + returnFiber = Object.prototype.toString.call(newChild); + throw Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === returnFiber + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : returnFiber) + + "). If you meant to render a collection of children, use an array instead." + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { @@ -2855,7 +2854,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (newChild = createFiberFromFragment( newChild, @@ -2887,7 +2886,7 @@ function ChildReconciler(shouldTrackSideEffects) { ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key ? null : updateFragment(returnFiber, oldFiber, newChild, lanes, null); @@ -2926,7 +2925,7 @@ function ChildReconciler(shouldTrackSideEffects) { updatePortal(returnFiber, existingChildren, newChild, lanes) ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (existingChildren = existingChildren.get(newIdx) || null), updateFragment(returnFiber, existingChildren, newChild, lanes, null) @@ -3109,20 +3108,19 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.type === REACT_FRAGMENT_TYPE && null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); - var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) + if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; + var key = newChild.key; for ( isUnkeyedTopLevelFragment = currentFirstChild; null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - isObject = newChild.type; - if (isObject === REACT_FRAGMENT_TYPE) { + if (isUnkeyedTopLevelFragment.key === key) { + key = newChild.type; + if (key === REACT_FRAGMENT_TYPE) { if (7 === isUnkeyedTopLevelFragment.tag) { deleteRemainingChildren( returnFiber, @@ -3136,7 +3134,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber = currentFirstChild; break a; } - } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + } else if (isUnkeyedTopLevelFragment.elementType === key) { deleteRemainingChildren( returnFiber, isUnkeyedTopLevelFragment.sibling @@ -3228,6 +3226,22 @@ function ChildReconciler(shouldTrackSideEffects) { } return placeSingleChild(returnFiber); } + if (isArrayImpl(newChild)) + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + if (getIteratorFn(newChild)) + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + throwOnInvalidObjectType(returnFiber, newChild); + } if ("string" === typeof newChild || "number" === typeof newChild) return ( (newChild = "" + newChild), @@ -3246,21 +3260,6 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); - if (isArray(newChild)) - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - if (getIteratorFn(newChild)) - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - isObject && throwOnInvalidObjectType(returnFiber, newChild); if ("undefined" === typeof newChild && !isUnkeyedTopLevelFragment) switch (returnFiber.tag) { case 1: @@ -3725,7 +3724,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(263168, 4, create, deps); + return mountEffectImpl(1049600, 4, create, deps); } function updateEffect(create, deps) { return updateEffectImpl(1024, 4, create, deps); @@ -3960,7 +3959,7 @@ var ContextOnlyDispatcher = { isPending = _mountState2[0]; _mountState2 = startTransition.bind(null, _mountState2[1]); mountWorkInProgressHook().memoizedState = _mountState2; - return [_mountState2, isPending]; + return [isPending, _mountState2]; }, useMutableSource: function(source, getSnapshot, subscribe) { var hook = mountWorkInProgressHook(); @@ -4009,8 +4008,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = updateReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4051,8 +4051,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = rerenderReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4221,7 +4222,6 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - markSpawnedWork(1073741824), (workInProgress.lanes = workInProgress.childLanes = 1073741824), (workInProgress.memoizedState = { baseLanes: current, @@ -4595,7 +4595,6 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { )), (workInProgress.memoizedState = SUSPENDED_MARKER), (workInProgress.lanes = 4194304), - markSpawnedWork(4194304), current ); renderLanes = createFiberFromOffscreen( @@ -4749,7 +4748,7 @@ function updateSuspenseFallbackChildren( (primaryChildren.treeBaseDuration = current.treeBaseDuration)), (workInProgress.deletions = null)) : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 262144)); + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); null !== currentFallbackChildFragment ? (fallbackChildren = createWorkInProgress( currentFallbackChildFragment, @@ -4951,14 +4950,14 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$63 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), + for (var lastTailNode$65 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$65 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$63 + null === lastTailNode$65 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$63.sibling = null); + : (lastTailNode$65.sibling = null); } } function bubbleProperties(completedWork) { @@ -4970,53 +4969,53 @@ function bubbleProperties(completedWork) { if (didBailout) if (0 !== (completedWork.mode & 2)) { for ( - var treeBaseDuration$65 = completedWork.selfBaseDuration, - child$66 = completedWork.child; - null !== child$66; + var treeBaseDuration$67 = completedWork.selfBaseDuration, + child$68 = completedWork.child; + null !== child$68; ) - (newChildLanes |= child$66.lanes | child$66.childLanes), - (subtreeFlags |= child$66.subtreeFlags & 262144), - (subtreeFlags |= child$66.flags & 262144), - (treeBaseDuration$65 += child$66.treeBaseDuration), - (child$66 = child$66.sibling); - completedWork.treeBaseDuration = treeBaseDuration$65; + (newChildLanes |= child$68.lanes | child$68.childLanes), + (subtreeFlags |= child$68.subtreeFlags & 1835008), + (subtreeFlags |= child$68.flags & 1835008), + (treeBaseDuration$67 += child$68.treeBaseDuration), + (child$68 = child$68.sibling); + completedWork.treeBaseDuration = treeBaseDuration$67; } else for ( - treeBaseDuration$65 = completedWork.child; - null !== treeBaseDuration$65; + treeBaseDuration$67 = completedWork.child; + null !== treeBaseDuration$67; ) (newChildLanes |= - treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), - (subtreeFlags |= treeBaseDuration$65.subtreeFlags & 262144), - (subtreeFlags |= treeBaseDuration$65.flags & 262144), - (treeBaseDuration$65.return = completedWork), - (treeBaseDuration$65 = treeBaseDuration$65.sibling); + treeBaseDuration$67.lanes | treeBaseDuration$67.childLanes), + (subtreeFlags |= treeBaseDuration$67.subtreeFlags & 1835008), + (subtreeFlags |= treeBaseDuration$67.flags & 1835008), + (treeBaseDuration$67.return = completedWork), + (treeBaseDuration$67 = treeBaseDuration$67.sibling); else if (0 !== (completedWork.mode & 2)) { - treeBaseDuration$65 = completedWork.actualDuration; - child$66 = completedWork.selfBaseDuration; + treeBaseDuration$67 = completedWork.actualDuration; + child$68 = completedWork.selfBaseDuration; for (var child = completedWork.child; null !== child; ) (newChildLanes |= child.lanes | child.childLanes), (subtreeFlags |= child.subtreeFlags), (subtreeFlags |= child.flags), - (treeBaseDuration$65 += child.actualDuration), - (child$66 += child.treeBaseDuration), + (treeBaseDuration$67 += child.actualDuration), + (child$68 += child.treeBaseDuration), (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$65; - completedWork.treeBaseDuration = child$66; + completedWork.actualDuration = treeBaseDuration$67; + completedWork.treeBaseDuration = child$68; } else for ( - treeBaseDuration$65 = completedWork.child; - null !== treeBaseDuration$65; + treeBaseDuration$67 = completedWork.child; + null !== treeBaseDuration$67; ) (newChildLanes |= - treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), - (subtreeFlags |= treeBaseDuration$65.subtreeFlags), - (subtreeFlags |= treeBaseDuration$65.flags), - (treeBaseDuration$65.return = completedWork), - (treeBaseDuration$65 = treeBaseDuration$65.sibling); + treeBaseDuration$67.lanes | treeBaseDuration$67.childLanes), + (subtreeFlags |= treeBaseDuration$67.subtreeFlags), + (subtreeFlags |= treeBaseDuration$67.flags), + (treeBaseDuration$67.return = completedWork), + (treeBaseDuration$67 = treeBaseDuration$67.sibling); completedWork.subtreeFlags |= subtreeFlags; completedWork.childLanes = newChildLanes; return didBailout; @@ -5228,7 +5227,7 @@ function completeWork(current, workInProgress, renderLanes) { for (newProps = workInProgress.child; null !== newProps; ) (renderLanes = newProps), (updatePayload = current), - (renderLanes.flags &= 262146), + (renderLanes.flags &= 1835010), (type = renderLanes.alternate), null === type ? ((renderLanes.childLanes = 0), @@ -5275,8 +5274,7 @@ function completeWork(current, workInProgress, renderLanes) { ((workInProgress.flags |= 128), (newProps = !0), cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304), - markSpawnedWork(4194304)); + (workInProgress.lanes = 4194304)); } else { if (!newProps) @@ -5303,8 +5301,7 @@ function completeWork(current, workInProgress, renderLanes) { ((workInProgress.flags |= 128), (newProps = !0), cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304), - markSpawnedWork(4194304)); + (workInProgress.lanes = 4194304)); type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) @@ -5606,67 +5603,71 @@ function commitHookEffectListMount(tag, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & tag) === tag) { - var create$84 = effect.create; - effect.destroy = create$84(); + var create$86 = effect.create; + effect.destroy = create$86(); } effect = effect.next; } while (effect !== finishedWork); } } function hideOrUnhideAllChildren(finishedWork, isHidden) { - for (var node = finishedWork; ; ) { + for (var hostSubtreeRoot = null, 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 ( - ((22 !== node.tag && 23 !== node.tag) || - null === node.memoizedState || - node === finishedWork) && - null !== node.child - ) { - node.child.return = node; - node = node.child; - continue; + if (null === hostSubtreeRoot) { + hostSubtreeRoot = node; + 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) { + if (null === hostSubtreeRoot) throw Error("Not yet implemented."); + } else if ( + ((22 !== node.tag && 23 !== node.tag) || + null === node.memoizedState || + node === finishedWork) && + 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; + hostSubtreeRoot === node && (hostSubtreeRoot = null); node = node.return; } + hostSubtreeRoot === node && (hostSubtreeRoot = null); node.sibling.return = node.return; node = node.sibling; } @@ -5812,10 +5813,9 @@ function commitPlacement(finishedWork) { : insertOrAppendPlacementNode(finishedWork, parentFiber, parent); } function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - if (((node = isHost ? node.stateNode : node.stateNode.instance), before)) { + var tag = node.tag; + if (5 === tag || 6 === tag) + if (((node = node.stateNode), before)) { if ("number" === typeof parent) throw Error("Container does not support insertBefore operation"); } else @@ -5833,58 +5833,57 @@ function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { (node = node.sibling); } function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - (node = isHost ? node.stateNode : node.stateNode.instance), - before - ? ((tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - (before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [before], - [], - [], - [] - )) - : ((before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - ["number" === typeof node ? node : node._nativeTag], - [before], - [] - ))) - : ((before = "number" === typeof node ? node : node._nativeTag), - (tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - tag.push(node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [tag.length - 1], - [], - [], - [] - )) - : (tag.push(node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - [before], - [tag.length - 1], - [] - ))); + var tag = node.tag; + if (5 === tag || 6 === tag) + if (((node = node.stateNode), before)) { + tag = parent._children; + var index = tag.indexOf(node); + 0 <= index + ? (tag.splice(index, 1), + (before = tag.indexOf(before)), + tag.splice(before, 0, node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [index], + [before], + [], + [], + [] + )) + : ((before = tag.indexOf(before)), + tag.splice(before, 0, node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + ["number" === typeof node ? node : node._nativeTag], + [before], + [] + )); + } else + (before = "number" === typeof node ? node : node._nativeTag), + (tag = parent._children), + (index = tag.indexOf(node)), + 0 <= index + ? (tag.splice(index, 1), + tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [index], + [tag.length - 1], + [], + [], + [] + )) + : (tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + [before], + [tag.length - 1], + [] + )); else if (4 !== tag && ((node = node.child), null !== node)) for ( insertOrAppendPlacementNode(node, before, parent), node = node.sibling; @@ -6093,10 +6092,7 @@ function attachSuspenseRetryListeners(finishedWork) { wakeables.forEach(function(wakeable) { var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); retryCache.has(wakeable) || - (!0 !== wakeable.__reactDoNotTraceInteractions && - (retry = tracing.unstable_wrap(retry)), - retryCache.add(wakeable), - wakeable.then(retry, retry)); + (retryCache.add(wakeable), wakeable.then(retry, retry)); }); } } @@ -6167,36 +6163,35 @@ function commitMutationEffects(root, firstChild) { } } } -function commitLayoutEffects(finishedWork, root) { +function commitLayoutEffects(finishedWork) { for (nextEffect = finishedWork; null !== nextEffect; ) { var fiber = nextEffect, firstChild = fiber.child; if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) (firstChild.return = fiber), (nextEffect = firstChild); else - for (fiber = finishedWork, firstChild = root; null !== nextEffect; ) { - var fiber$jscomp$0 = nextEffect; - if (0 !== (fiber$jscomp$0.flags & 324)) { - var current = fiber$jscomp$0.alternate; + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; try { - var finishedRoot = firstChild; - if (0 !== (fiber$jscomp$0.flags & 68)) - switch (fiber$jscomp$0.tag) { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { case 0: case 11: case 15: - commitHookEffectListMount(3, fiber$jscomp$0); + commitHookEffectListMount(3, firstChild); break; case 1: - var instance = fiber$jscomp$0.stateNode; - if (fiber$jscomp$0.flags & 4) + var instance = firstChild.stateNode; + if (firstChild.flags & 4) if (null === current) instance.componentDidMount(); else { var prevProps = - fiber$jscomp$0.elementType === fiber$jscomp$0.type + firstChild.elementType === firstChild.type ? current.memoizedProps : resolveDefaultProps( - fiber$jscomp$0.type, + firstChild.type, current.memoizedProps ); instance.componentDidUpdate( @@ -6205,27 +6200,23 @@ function commitLayoutEffects(finishedWork, root) { instance.__reactInternalSnapshotBeforeUpdate ); } - var updateQueue = fiber$jscomp$0.updateQueue; + var updateQueue = firstChild.updateQueue; null !== updateQueue && - commitUpdateQueue(fiber$jscomp$0, updateQueue, instance); + commitUpdateQueue(firstChild, updateQueue, instance); break; case 3: - var updateQueue$85 = fiber$jscomp$0.updateQueue; - if (null !== updateQueue$85) { - finishedRoot = null; - if (null !== fiber$jscomp$0.child) - switch (fiber$jscomp$0.child.tag) { + var updateQueue$87 = firstChild.updateQueue; + if (null !== updateQueue$87) { + var instance$88 = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { case 5: - finishedRoot = fiber$jscomp$0.child.stateNode; + instance$88 = firstChild.child.stateNode; break; case 1: - finishedRoot = fiber$jscomp$0.child.stateNode; + instance$88 = firstChild.child.stateNode; } - commitUpdateQueue( - fiber$jscomp$0, - updateQueue$85, - finishedRoot - ); + commitUpdateQueue(firstChild, updateQueue$87, instance$88); } break; case 5: @@ -6235,18 +6226,17 @@ function commitLayoutEffects(finishedWork, root) { case 4: break; case 12: - var onRender = fiber$jscomp$0.memoizedProps.onRender, - commitTime$88 = commitTime; + var onRender = firstChild.memoizedProps.onRender; + instance$88 = commitTime; current = null === current ? "mount" : "update"; "function" === typeof onRender && onRender( - fiber$jscomp$0.memoizedProps.id, + firstChild.memoizedProps.id, current, - fiber$jscomp$0.actualDuration, - fiber$jscomp$0.treeBaseDuration, - fiber$jscomp$0.actualStartTime, - commitTime$88, - finishedRoot.memoizedInteractions + firstChild.actualDuration, + firstChild.treeBaseDuration, + firstChild.actualStartTime, + instance$88 ); break; case 13: @@ -6262,48 +6252,45 @@ function commitLayoutEffects(finishedWork, root) { "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." ); } - if (fiber$jscomp$0.flags & 256) { - finishedRoot = void 0; - var ref = fiber$jscomp$0.ref; + if (firstChild.flags & 256) { + instance$88 = void 0; + var ref = firstChild.ref; if (null !== ref) { - var instance$jscomp$0 = fiber$jscomp$0.stateNode; - switch (fiber$jscomp$0.tag) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { case 5: - finishedRoot = instance$jscomp$0; + instance$88 = instance$jscomp$0; break; default: - finishedRoot = instance$jscomp$0; + instance$88 = instance$jscomp$0; } "function" === typeof ref - ? ref(finishedRoot) - : (ref.current = finishedRoot); + ? ref(instance$88) + : (ref.current = instance$88); } } } catch (error) { - captureCommitPhaseError( - fiber$jscomp$0, - fiber$jscomp$0.return, - error - ); + captureCommitPhaseError(firstChild, firstChild.return, error); } } - if (fiber$jscomp$0 === fiber) { + if (firstChild === fiber) { nextEffect = null; break; } - finishedRoot = fiber$jscomp$0.sibling; - if (null !== finishedRoot) { - finishedRoot.return = fiber$jscomp$0.return; - nextEffect = finishedRoot; + instance$88 = firstChild.sibling; + if (null !== instance$88) { + instance$88.return = firstChild.return; + nextEffect = instance$88; break; } - nextEffect = fiber$jscomp$0.return; + nextEffect = firstChild.return; } } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -6325,7 +6312,6 @@ var ceil = Math.ceil, pendingPassiveEffectsLanes = 0, nestedUpdateCount = 0, rootWithNestedUpdates = null, - spawnedWorkDuringRender = null, currentEventTime = -1, currentEventTransitionLane = 0; function requestEventTime() { @@ -6365,15 +6351,13 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { markRootSuspended$1(root, workInProgressRootRenderLanes)); 1 === lane ? 0 !== (executionContext & 4) && 0 === (executionContext & 24) - ? (schedulePendingInteractions(root, lane), performSyncWorkOnRoot(root)) + ? performSyncWorkOnRoot(root) : (ensureRootIsScheduled(root, eventTime), - schedulePendingInteractions(root, lane), 0 === executionContext && 0 === (fiber.mode & 1) && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue())) - : (ensureRootIsScheduled(root, eventTime), - schedulePendingInteractions(root, lane)); + includesLegacySyncCallbacks && flushSyncCallbacks())) + : ensureRootIsScheduled(root, eventTime); return root; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { @@ -6395,8 +6379,7 @@ function ensureRootIsScheduled(root, currentTime) { suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes, expirationTimes = root.expirationTimes, - lanes = root.pendingLanes, - expiredLanes = 0; + lanes = root.pendingLanes; 0 < lanes; ) { @@ -6406,10 +6389,9 @@ function ensureRootIsScheduled(root, currentTime) { if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) expirationTimes[index$6] = computeExpirationTime(lane, currentTime); - } else expirationTime <= currentTime && (expiredLanes |= lane); + } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } - 0 !== expiredLanes && markRootExpired(root, expiredLanes); suspendedLanes = getNextLanes( root, root === workInProgressRoot ? workInProgressRootRenderLanes : 0 @@ -6424,11 +6406,17 @@ function ensureRootIsScheduled(root, currentTime) { ) { null != existingCallbackNode && cancelCallback(existingCallbackNode); if (1 === currentTime) - (existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? (syncQueue = [existingCallbackNode]) - : syncQueue.push(existingCallbackNode), - scheduleCallback(ImmediatePriority, flushSyncCallbackQueue), + 0 === root.tag + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + (includesLegacySyncCallbacks = !0), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)) + : ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), (existingCallbackNode = null); else { switch (lanesToEventPriority(suspendedLanes)) { @@ -6469,45 +6457,48 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - if (didTimeout) - return ( - markRootExpired(root, lanes), ensureRootIsScheduled(root, now()), null - ); - var lanes$jscomp$0 = lanes; - didTimeout = executionContext; - executionContext |= 8; - var prevDispatcher = pushDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== lanes$jscomp$0 - ) - (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, lanes$jscomp$0), - startWorkOnPendingInteractions(root, lanes$jscomp$0); - lanes$jscomp$0 = pushInteractions(root); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = lanes$jscomp$0; - ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = didTimeout; - null !== workInProgress - ? (didTimeout = 0) - : ((workInProgressRoot = null), - (workInProgressRootRenderLanes = 0), - (didTimeout = workInProgressRootExitStatus)); + var JSCompiler_inline_result = + 0 !== (lanes & root.expiredLanes) + ? !1 + : 0 !== (root.current.mode & 32) + ? !0 + : 0 === (lanes & 30); + if (JSCompiler_inline_result && !didTimeout) { + didTimeout = lanes; + JSCompiler_inline_result = executionContext; + executionContext |= 8; + var prevDispatcher = pushDispatcher(); + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== didTimeout + ) + (workInProgressRootRenderTargetTime = now() + 500), + prepareFreshStack(root, didTimeout); + do + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + ReactCurrentDispatcher$2.current = prevDispatcher; + executionContext = JSCompiler_inline_result; + null !== workInProgress + ? (didTimeout = 0) + : ((workInProgressRoot = null), + (workInProgressRootRenderLanes = 0), + (didTimeout = workInProgressRootExitStatus)); + } else didTimeout = renderRootSync(root, lanes); if (0 !== didTimeout) { 2 === didTimeout && ((executionContext |= 32), root.hydrate && (root.hydrate = !1), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + (JSCompiler_inline_result = getLanesToRetrySynchronouslyOnError(root)), + 0 !== JSCompiler_inline_result && + ((lanes = JSCompiler_inline_result), + (didTimeout = renderRootSync(root, JSCompiler_inline_result)))); if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6531,10 +6522,10 @@ function performConcurrentWorkOnRoot(root, didTimeout) { 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; - prevDispatcher = root.suspendedLanes; - if ((prevDispatcher & lanes) !== lanes) { + JSCompiler_inline_result = root.suspendedLanes; + if ((JSCompiler_inline_result & lanes) !== lanes) { requestEventTime(); - root.pingedLanes |= root.suspendedLanes & prevDispatcher; + root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result; break; } root.timeoutHandle = scheduleTimeout( @@ -6549,14 +6540,15 @@ function performConcurrentWorkOnRoot(root, didTimeout) { markRootSuspended$1(root, lanes); if ((lanes & 4194240) === lanes) break; didTimeout = root.eventTimes; - for (prevDispatcher = -1; 0 < lanes; ) { + for (JSCompiler_inline_result = -1; 0 < lanes; ) { var index$5 = 31 - clz32(lanes); - lanes$jscomp$0 = 1 << index$5; + prevDispatcher = 1 << index$5; index$5 = didTimeout[index$5]; - index$5 > prevDispatcher && (prevDispatcher = index$5); - lanes &= ~lanes$jscomp$0; + index$5 > JSCompiler_inline_result && + (JSCompiler_inline_result = index$5); + lanes &= ~prevDispatcher; } - lanes = prevDispatcher; + lanes = JSCompiler_inline_result; lanes = now() - lanes; lanes = (120 > lanes @@ -6609,17 +6601,16 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 24)) throw Error("Should not already be working."); flushPassiveEffects(); - var lanes; - if ((lanes = root === workInProgressRoot)) - lanes = 0 !== (root.entanglements[0] & workInProgressRootRenderLanes); - lanes = lanes ? workInProgressRootRenderLanes : getNextLanes(root, 0); + var lanes = getNextLanes(root, 0); + if (0 === (lanes & 1)) return ensureRootIsScheduled(root, now()), null; var exitStatus = renderRootSync(root, lanes); - 0 !== root.tag && - 2 === exitStatus && - ((executionContext |= 32), - root.hydrate && (root.hydrate = !1), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + if (0 !== root.tag && 2 === exitStatus) { + executionContext |= 32; + root.hydrate && (root.hydrate = !1); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + 0 !== errorRetryLanes && + ((lanes = errorRetryLanes), (exitStatus = renderRootSync(root, lanes))); + } if (1 === exitStatus) throw ((exitStatus = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6704,7 +6695,6 @@ function prepareFreshStack(root, lanes) { } interleavedQueues = null; } - spawnedWorkDuringRender = null; } function handleError(root$jscomp$0, thrownValue) { do { @@ -6764,15 +6754,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$79 = returnFiber; + workInProgress$81 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$79.tag)) { - var nextState = workInProgress$79.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$81.tag)) { + var nextState = workInProgress$81.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$79.memoizedProps; + var props = workInProgress$81.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6784,17 +6774,17 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$79.updateQueue; + var wakeables = workInProgress$81.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$79.updateQueue = updateQueue; + workInProgress$81.updateQueue = updateQueue; } else wakeables.add(wakeable); if ( - 0 === (workInProgress$79.mode & 1) && - workInProgress$79 !== returnFiber + 0 === (workInProgress$81.mode & 1) && + workInProgress$81 !== returnFiber ) { - workInProgress$79.flags |= 128; + workInProgress$81.flags |= 128; sourceFiber.flags |= 32768; sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) @@ -6827,12 +6817,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$79.flags |= 16384; - workInProgress$79.lanes = thrownValue; + workInProgress$81.flags |= 16384; + workInProgress$81.lanes = thrownValue; break a; } - workInProgress$79 = workInProgress$79.return; - } while (null !== workInProgress$79); + workInProgress$81 = workInProgress$81.return; + } while (null !== workInProgress$81); value = Error( (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6841,47 +6831,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$79 = returnFiber; + workInProgress$81 = returnFiber; do { - switch (workInProgress$79.tag) { + switch (workInProgress$81.tag) { case 3: root = value; - workInProgress$79.flags |= 16384; + workInProgress$81.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$79.lanes |= thrownValue; - var update$80 = createRootErrorUpdate( - workInProgress$79, + workInProgress$81.lanes |= thrownValue; + var update$82 = createRootErrorUpdate( + workInProgress$81, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$79, update$80); + enqueueCapturedUpdate(workInProgress$81, update$82); break a; case 1: root = value; - var ctor = workInProgress$79.type, - instance = workInProgress$79.stateNode; + var ctor = workInProgress$81.type, + instance = workInProgress$81.stateNode; if ( - 0 === (workInProgress$79.flags & 128) && + 0 === (workInProgress$81.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$79.flags |= 16384; + workInProgress$81.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$79.lanes |= thrownValue; - var update$83 = createClassErrorUpdate( - workInProgress$79, + workInProgress$81.lanes |= thrownValue; + var update$85 = createClassErrorUpdate( + workInProgress$81, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$79, update$83); + enqueueCapturedUpdate(workInProgress$81, update$85); break a; } } - workInProgress$79 = workInProgress$79.return; - } while (null !== workInProgress$79); + workInProgress$81 = workInProgress$81.return; + } while (null !== workInProgress$81); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6899,18 +6889,12 @@ function pushDispatcher() { ReactCurrentDispatcher$2.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } -function pushInteractions(root) { - var prevInteractions = tracing.__interactionsRef.current; - tracing.__interactionsRef.current = root.memoizedInteractions; - return prevInteractions; -} function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; executionContext |= 8; var prevDispatcher = pushDispatcher(); - if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) - prepareFreshStack(root, lanes), startWorkOnPendingInteractions(root, lanes); - lanes = pushInteractions(root); + (workInProgressRoot === root && workInProgressRootRenderLanes === lanes) || + prepareFreshStack(root, lanes); do try { workLoopSync(); @@ -6920,7 +6904,6 @@ function renderRootSync(root, lanes) { } while (1); resetContextDependencies(); - tracing.__interactionsRef.current = lanes; executionContext = prevExecutionContext; ReactCurrentDispatcher$2.current = prevDispatcher; if (null !== workInProgress) @@ -7000,12 +6983,15 @@ function completeUnitOfWork(unitOfWork) { 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } function commitRoot(root) { - var previousUpdateLanePriority = currentUpdatePriority; + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig$2.transition; try { - (currentUpdatePriority = 1), + (ReactCurrentBatchConfig$2.transition = 0), + (currentUpdatePriority = 1), commitRootImpl(root, previousUpdateLanePriority); } finally { - currentUpdatePriority = previousUpdateLanePriority; + (ReactCurrentBatchConfig$2.transition = prevTransition), + (currentUpdatePriority = previousUpdateLanePriority); } return null; } @@ -7040,11 +7026,12 @@ function commitRootImpl(root, renderPriorityLevel) { })); remainingLanes = 0 !== (finishedWork.flags & 8054); if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { - remainingLanes = currentUpdatePriority; + remainingLanes = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = currentUpdatePriority; currentUpdatePriority = 1; var prevExecutionContext = executionContext; executionContext |= 16; - var prevInteractions = pushInteractions(root); ReactCurrentOwner$2.current = null; commitBeforeMutationEffects(root, finishedWork); commitTime = now$1(); @@ -7052,29 +7039,16 @@ function commitRootImpl(root, renderPriorityLevel) { root.current = finishedWork; commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - tracing.__interactionsRef.current = prevInteractions; executionContext = prevExecutionContext; - currentUpdatePriority = remainingLanes; + currentUpdatePriority = previousPriority; + ReactCurrentBatchConfig$2.transition = remainingLanes; } else (root.current = finishedWork), (commitTime = now$1()); - if ((prevExecutionContext = rootDoesHavePassiveEffects)) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; - if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) { - prevInteractions = spawnedWorkDuringRender; - spawnedWorkDuringRender = null; - for (var i = 0; i < prevInteractions.length; i++) - scheduleInteractions( - root, - prevInteractions[i], - root.memoizedInteractions - ); - } - schedulePendingInteractions(root, remainingLanes); - } else legacyErrorBoundariesThatAlreadyFailed = null; - prevExecutionContext || finishPendingInteractions(root, lanes); + 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ @@ -7088,28 +7062,31 @@ function commitRootImpl(root, renderPriorityLevel) { (firstUncaughtError = null), root); if (0 !== (executionContext & 4)) return null; - flushSyncCallbackQueue(); + 0 !== (pendingPassiveEffectsLanes & 1) && + 0 !== root.tag && + flushPassiveEffects(); + flushSyncCallbacks(); return null; } function flushPassiveEffects() { - if (0 !== pendingPassiveEffectsLanes) { - var b = lanesToEventPriority(pendingPassiveEffectsLanes), + if (null !== rootWithPendingPassiveEffects) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), + prevTransition = ReactCurrentBatchConfig$2.transition, previousPriority = currentUpdatePriority; try { - currentUpdatePriority = 16 < b ? 16 : b; + ReactCurrentBatchConfig$2.transition = 0; + currentUpdatePriority = 16 > renderPriority ? 16 : renderPriority; if (null === rootWithPendingPassiveEffects) var JSCompiler_inline_result = !1; else { - b = rootWithPendingPassiveEffects; - var lanes = pendingPassiveEffectsLanes; + renderPriority = rootWithPendingPassiveEffects; rootWithPendingPassiveEffects = null; pendingPassiveEffectsLanes = 0; if (0 !== (executionContext & 24)) throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 16; - var prevInteractions = pushInteractions(b); - for (nextEffect = b.current; null !== nextEffect; ) { + for (nextEffect = renderPriority.current; null !== nextEffect; ) { var fiber = nextEffect, child = fiber.child; if (0 !== (nextEffect.flags & 16)) { @@ -7184,7 +7161,7 @@ function flushPassiveEffects() { nextEffect = fiber.return; } } - var finishedWork = b.current; + var finishedWork = renderPriority.current; for (nextEffect = finishedWork; null !== nextEffect; ) { child = nextEffect; var firstChild = child.child; @@ -7217,15 +7194,21 @@ function flushPassiveEffects() { nextEffect = deletions.return; } } - tracing.__interactionsRef.current = prevInteractions; - finishPendingInteractions(b, lanes); executionContext = prevExecutionContext; - flushSyncCallbackQueue(); + flushSyncCallbacks(); + if ( + injectedHook && + "function" === typeof injectedHook.onPostCommitFiberRoot + ) + try { + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); + } catch (err) {} JSCompiler_inline_result = !0; } return JSCompiler_inline_result; } finally { - currentUpdatePriority = previousPriority; + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$2.transition = prevTransition); } } return !1; @@ -7238,8 +7221,7 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { rootFiber = markUpdateLaneFromFiberToRoot(rootFiber, 1); null !== rootFiber && (markRootUpdated(rootFiber, 1, sourceFiber), - ensureRootIsScheduled(rootFiber, sourceFiber), - schedulePendingInteractions(rootFiber, 1)); + ensureRootIsScheduled(rootFiber, sourceFiber)); } function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) @@ -7280,8 +7262,7 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { ); null !== nearestMountedAncestor && (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), - ensureRootIsScheduled(nearestMountedAncestor, sourceFiber), - schedulePendingInteractions(nearestMountedAncestor, 1)); + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } @@ -7303,7 +7284,6 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { ? prepareFreshStack(root, 0) : (workInProgressRootPingedLanes |= pingedLanes)); ensureRootIsScheduled(root, wakeable); - schedulePendingInteractions(root, pingedLanes); } function resolveRetryWakeable(boundaryFiber, wakeable) { var retryCache = boundaryFiber.stateNode; @@ -7319,8 +7299,7 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && (markRootUpdated(boundaryFiber, wakeable, retryCache), - ensureRootIsScheduled(boundaryFiber, retryCache), - schedulePendingInteractions(boundaryFiber, wakeable)); + ensureRootIsScheduled(boundaryFiber, retryCache)); } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { @@ -7452,14 +7431,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? nextValue.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; - "function" === typeof getDerivedStateFromProps && - applyDerivedStateFromProps( - workInProgress, - updateLanes, - getDerivedStateFromProps, - current - ); nextValue.updater = classComponentUpdater; workInProgress.stateNode = nextValue; nextValue._reactInternals = workInProgress; @@ -7675,11 +7646,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateLanes = workInProgress.type._context; nextValue = workInProgress.pendingProps; hasContext = workInProgress.memoizedProps; - getDerivedStateFromProps = nextValue.value; + var newValue = nextValue.value; push(valueCursor, updateLanes._currentValue); - updateLanes._currentValue = getDerivedStateFromProps; + updateLanes._currentValue = newValue; if (null !== hasContext) - if (objectIs(hasContext.value, getDerivedStateFromProps)) { + if (objectIs(hasContext.value, newValue)) { if ( hasContext.children === nextValue.children && !didPerformWorkStackCursor.current @@ -7693,25 +7664,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - getDerivedStateFromProps = workInProgress.child, - null !== getDerivedStateFromProps && - (getDerivedStateFromProps.return = workInProgress); - null !== getDerivedStateFromProps; + newValue = workInProgress.child, + null !== newValue && (newValue.return = workInProgress); + null !== newValue; ) { - var list = getDerivedStateFromProps.dependencies; + var list = newValue.dependencies; if (null !== list) { - hasContext = getDerivedStateFromProps.child; + hasContext = newValue.child; for ( var dependency = list.firstContext; null !== dependency; ) { if (dependency.context === updateLanes) { - if (1 === getDerivedStateFromProps.tag) { + if (1 === newValue.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; - var updateQueue = getDerivedStateFromProps.updateQueue; + var updateQueue = newValue.updateQueue; if (null !== updateQueue) { updateQueue = updateQueue.shared; var pending = updateQueue.pending; @@ -7722,13 +7692,10 @@ beginWork$1 = function(current, workInProgress, renderLanes) { updateQueue.pending = dependency; } } - getDerivedStateFromProps.lanes |= renderLanes; - dependency = getDerivedStateFromProps.alternate; + newValue.lanes |= renderLanes; + dependency = newValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - getDerivedStateFromProps.return, - renderLanes - ); + scheduleWorkOnParentPath(newValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7736,32 +7703,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else hasContext = - 10 === getDerivedStateFromProps.tag - ? getDerivedStateFromProps.type === workInProgress.type + 10 === newValue.tag + ? newValue.type === workInProgress.type ? null - : getDerivedStateFromProps.child - : getDerivedStateFromProps.child; - if (null !== hasContext) - hasContext.return = getDerivedStateFromProps; + : newValue.child + : newValue.child; + if (null !== hasContext) hasContext.return = newValue; else - for ( - hasContext = getDerivedStateFromProps; - null !== hasContext; - - ) { + for (hasContext = newValue; null !== hasContext; ) { if (hasContext === workInProgress) { hasContext = null; break; } - getDerivedStateFromProps = hasContext.sibling; - if (null !== getDerivedStateFromProps) { - getDerivedStateFromProps.return = hasContext.return; - hasContext = getDerivedStateFromProps; + newValue = hasContext.sibling; + if (null !== newValue) { + newValue.return = hasContext.return; + hasContext = newValue; break; } hasContext = hasContext.return; } - getDerivedStateFromProps = hasContext; + newValue = hasContext; } reconcileChildren( current, @@ -7850,93 +7812,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { "). This error is likely caused by a bug in React. Please file an issue." ); }; -function markSpawnedWork(lane) { - null === spawnedWorkDuringRender - ? (spawnedWorkDuringRender = [lane]) - : spawnedWorkDuringRender.push(lane); -} -function scheduleInteractions(root, lane, interactions) { - if (0 < interactions.size) { - var pendingInteractionMap = root.pendingInteractionMap, - pendingInteractions = pendingInteractionMap.get(lane); - null != pendingInteractions - ? interactions.forEach(function(interaction) { - pendingInteractions.has(interaction) || interaction.__count++; - pendingInteractions.add(interaction); - }) - : (pendingInteractionMap.set(lane, new Set(interactions)), - interactions.forEach(function(interaction) { - interaction.__count++; - })); - pendingInteractionMap = tracing.__subscriberRef.current; - if (null !== pendingInteractionMap) - pendingInteractionMap.onWorkScheduled( - interactions, - 1e3 * lane + root.interactionThreadID - ); - } -} -function schedulePendingInteractions(root, lane) { - scheduleInteractions(root, lane, tracing.__interactionsRef.current); -} -function startWorkOnPendingInteractions(root, lanes) { - var interactions = new Set(); - root.pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledLane - ) { - 0 !== (lanes & scheduledLane) && - scheduledInteractions.forEach(function(interaction) { - return interactions.add(interaction); - }); - }); - root.memoizedInteractions = interactions; - if (0 < interactions.size) { - var subscriber = tracing.__subscriberRef.current; - if (null !== subscriber) { - root = 1e3 * lanes + root.interactionThreadID; - try { - subscriber.onWorkStarted(interactions, root); - } catch (error) { - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } - } - } -} -function finishPendingInteractions(root, committedLanes) { - var remainingLanesAfterCommit = root.pendingLanes; - try { - var subscriber = tracing.__subscriberRef.current; - if (null !== subscriber && 0 < root.memoizedInteractions.size) - subscriber.onWorkStopped( - root.memoizedInteractions, - 1e3 * committedLanes + root.interactionThreadID - ); - } catch (error) { - scheduleCallback(ImmediatePriority, function() { - throw error; - }); - } finally { - var pendingInteractionMap = root.pendingInteractionMap; - pendingInteractionMap.forEach(function(scheduledInteractions, lane) { - 0 === (remainingLanesAfterCommit & lane) && - (pendingInteractionMap.delete(lane), - scheduledInteractions.forEach(function(interaction) { - interaction.__count--; - if (null !== subscriber && 0 === interaction.__count) - try { - subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$96) { - scheduleCallback(ImmediatePriority, function() { - throw error$96; - }); - } - })); - }); - } -} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -7992,7 +7867,7 @@ function createWorkInProgress(current, pendingProps) { (workInProgress.deletions = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); - workInProgress.flags = current.flags & 262144; + workInProgress.flags = current.flags & 1835008; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -8033,10 +7908,7 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - 1 <= - (null == pendingProps.unstable_level - ? 1 - : pendingProps.unstable_level) && (mode |= 8); + mode |= 24; break; case REACT_PROFILER_TYPE: return ( @@ -8143,11 +8015,8 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.callbackPriority = 0; this.eventTimes = createLaneMap(0); this.expirationTimes = createLaneMap(-1); - this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; + this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.expiredLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; this.entanglements = createLaneMap(0); - this.interactionThreadID = tracing.unstable_getThreadID(); - this.memoizedInteractions = new Set(); - this.pendingInteractionMap = new Map(); } function createPortal(children, containerInfo, implementation) { var key = @@ -8265,14 +8134,14 @@ batchedUpdatesImpl = function(fn, a) { (executionContext = prevExecutionContext), 0 === executionContext && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue()); + includesLegacySyncCallbacks && flushSyncCallbacks()); } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1012 = { + devToolsConfig$jscomp$inline_1010 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.3", + version: "17.0.3-2d8d133e1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8287,11 +8156,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1275 = { - bundleType: devToolsConfig$jscomp$inline_1012.bundleType, - version: devToolsConfig$jscomp$inline_1012.version, - rendererPackageName: devToolsConfig$jscomp$inline_1012.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1012.rendererConfig, +var internals$jscomp$inline_1271 = { + bundleType: devToolsConfig$jscomp$inline_1010.bundleType, + version: devToolsConfig$jscomp$inline_1010.version, + rendererPackageName: devToolsConfig$jscomp$inline_1010.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1010.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8306,25 +8175,26 @@ var internals$jscomp$inline_1275 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1012.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1010.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, - getCurrentFiber: null + getCurrentFiber: null, + reconcilerVersion: "17.0.3-2d8d133e1" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1276 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1272 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1276.isDisabled && - hook$jscomp$inline_1276.supportsFiber + !hook$jscomp$inline_1272.isDisabled && + hook$jscomp$inline_1272.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1276.inject( - internals$jscomp$inline_1275 + (rendererID = hook$jscomp$inline_1272.inject( + internals$jscomp$inline_1271 )), - (injectedHook = hook$jscomp$inline_1276); + (injectedHook = hook$jscomp$inline_1272); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index 726a064c70b56a..876b06a345a249 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -8,15 +8,14 @@ * @nolint * @providesModule ReactNativeRenderer-profiling * @preventMunge - * @generated + * @generated SignedSource<<69fba3aae321ae1afa2449c55aef29f5>> */ "use strict"; require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), - Scheduler = require("scheduler"), - tracing = require("scheduler/tracing"); + Scheduler = require("scheduler"); function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -64,7 +63,8 @@ function invokeGuardedCallbackAndCatchFirstError( hasRethrowError || ((hasRethrowError = !0), (rethrowError = error)); } } -var getFiberCurrentPropsFromNode = null, +var isArrayImpl = Array.isArray, + getFiberCurrentPropsFromNode = null, getInstanceFromNode = null, getNodeFromInstance = null; function executeDispatch(event, listener, inst) { @@ -76,7 +76,7 @@ function executeDispatch(event, listener, inst) { function executeDirectDispatch(event) { var dispatchListener = event._dispatchListeners, dispatchInstance = event._dispatchInstances; - if (Array.isArray(dispatchListener)) + if (isArrayImpl(dispatchListener)) throw Error("executeDirectDispatch(...): Invalid `event`."); event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) @@ -290,36 +290,46 @@ function recordTouchEnd(touch) { (touchRecord.currentTimeStamp = timestampForTouch(touch)), (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); } -var ResponderTouchHistoryStore = { - recordTouchTrack: function(topLevelType, nativeEvent) { - if (isMoveish(topLevelType)) - nativeEvent.changedTouches.forEach(recordTouchMove); - else if (isStartish(topLevelType)) - nativeEvent.changedTouches.forEach(recordTouchStart), - (touchHistory.numberActiveTouches = nativeEvent.touches.length), - 1 === touchHistory.numberActiveTouches && - (touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier); - else if ( - "topTouchEnd" === topLevelType || - "topTouchCancel" === topLevelType - ) - if ( - (nativeEvent.changedTouches.forEach(recordTouchEnd), - (touchHistory.numberActiveTouches = nativeEvent.touches.length), - 1 === touchHistory.numberActiveTouches) +var instrumentationCallback, + ResponderTouchHistoryStore = { + instrument: function(callback) { + instrumentationCallback = callback; + }, + recordTouchTrack: function(topLevelType, nativeEvent) { + null != instrumentationCallback && + instrumentationCallback(topLevelType, nativeEvent); + if (isMoveish(topLevelType)) + nativeEvent.changedTouches.forEach(recordTouchMove); + else if (isStartish(topLevelType)) + nativeEvent.changedTouches.forEach(recordTouchStart), + (touchHistory.numberActiveTouches = nativeEvent.touches.length), + 1 === touchHistory.numberActiveTouches && + (touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier); + else if ( + "topTouchEnd" === topLevelType || + "topTouchCancel" === topLevelType ) - for (topLevelType = 0; topLevelType < touchBank.length; topLevelType++) - if ( - ((nativeEvent = touchBank[topLevelType]), - null != nativeEvent && nativeEvent.touchActive) - ) { - touchHistory.indexOfSingleActiveTouch = topLevelType; - break; - } - }, - touchHistory: touchHistory -}; + if ( + (nativeEvent.changedTouches.forEach(recordTouchEnd), + (touchHistory.numberActiveTouches = nativeEvent.touches.length), + 1 === touchHistory.numberActiveTouches) + ) + for ( + topLevelType = 0; + topLevelType < touchBank.length; + topLevelType++ + ) + if ( + ((nativeEvent = touchBank[topLevelType]), + null != nativeEvent && nativeEvent.touchActive) + ) { + touchHistory.indexOfSingleActiveTouch = topLevelType; + break; + } + }, + touchHistory: touchHistory + }; function accumulate(current, next) { if (null == next) throw Error( @@ -327,9 +337,9 @@ function accumulate(current, next) { ); return null == current ? next - : Array.isArray(current) + : isArrayImpl(current) ? current.concat(next) - : Array.isArray(next) + : isArrayImpl(next) ? [current].concat(next) : [current, next]; } @@ -339,12 +349,12 @@ function accumulateInto(current, next) { "accumulateInto(...): Accumulated items must not be null or undefined." ); if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; + if (isArrayImpl(current)) { + if (isArrayImpl(next)) return current.push.apply(current, next), current; current.push(next); return current; } - return Array.isArray(next) ? [current].concat(next) : [current, next]; + return isArrayImpl(next) ? [current].concat(next) : [current, next]; } function forEachAccumulated(arr, cb, scope) { Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); @@ -570,7 +580,7 @@ var ResponderEventPlugin = { b: { JSCompiler_temp = shouldSetEventType._dispatchListeners; targetInst = shouldSetEventType._dispatchInstances; - if (Array.isArray(JSCompiler_temp)) + if (isArrayImpl(JSCompiler_temp)) for ( depthA = 0; depthA < JSCompiler_temp.length && @@ -921,7 +931,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_226 = { +var injectedNamesToPlugins$jscomp$inline_224 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -956,34 +966,34 @@ var injectedNamesToPlugins$jscomp$inline_226 = { } } }, - isOrderingDirty$jscomp$inline_227 = !1, - pluginName$jscomp$inline_228; -for (pluginName$jscomp$inline_228 in injectedNamesToPlugins$jscomp$inline_226) + isOrderingDirty$jscomp$inline_225 = !1, + pluginName$jscomp$inline_226; +for (pluginName$jscomp$inline_226 in injectedNamesToPlugins$jscomp$inline_224) if ( - injectedNamesToPlugins$jscomp$inline_226.hasOwnProperty( - pluginName$jscomp$inline_228 + injectedNamesToPlugins$jscomp$inline_224.hasOwnProperty( + pluginName$jscomp$inline_226 ) ) { - var pluginModule$jscomp$inline_229 = - injectedNamesToPlugins$jscomp$inline_226[pluginName$jscomp$inline_228]; + var pluginModule$jscomp$inline_227 = + injectedNamesToPlugins$jscomp$inline_224[pluginName$jscomp$inline_226]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_228) || - namesToPlugins[pluginName$jscomp$inline_228] !== - pluginModule$jscomp$inline_229 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_226) || + namesToPlugins[pluginName$jscomp$inline_226] !== + pluginModule$jscomp$inline_227 ) { - if (namesToPlugins[pluginName$jscomp$inline_228]) + if (namesToPlugins[pluginName$jscomp$inline_226]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_228 + + pluginName$jscomp$inline_226 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_228 - ] = pluginModule$jscomp$inline_229; - isOrderingDirty$jscomp$inline_227 = !0; + pluginName$jscomp$inline_226 + ] = pluginModule$jscomp$inline_227; + isOrderingDirty$jscomp$inline_225 = !0; } } -isOrderingDirty$jscomp$inline_227 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_225 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1007,7 +1017,7 @@ function executeDispatchesAndReleaseTopLevel(e) { if (e) { var dispatchListeners = e._dispatchListeners, dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) + if (isArrayImpl(dispatchListeners)) for ( var i = 0; i < dispatchListeners.length && !e.isPropagationStopped(); @@ -1141,7 +1151,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1160,6 +1171,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1169,7 +1181,7 @@ function getIteratorFn(maybeIterable) { maybeIterable["@@iterator"]; return "function" === typeof maybeIterable ? maybeIterable : null; } -function getComponentName(type) { +function getComponentNameFromType(type) { if (null == type) return null; if ("function" === typeof type) return type.displayName || type.name || null; if ("string" === typeof type) return type; @@ -1186,6 +1198,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1195,22 +1209,83 @@ function getComponentName(type) { return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; - innerType = innerType.displayName || innerType.name || ""; + type = type.displayName; + type || + ((type = innerType.displayName || innerType.name || ""), + (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); + return type; + case REACT_MEMO_TYPE: return ( - type.displayName || - ("" !== innerType ? "ForwardRef(" + innerType + ")" : "ForwardRef") + (innerType = type.displayName || null), + null !== innerType + ? innerType + : getComponentNameFromType(type.type) || "Memo" ); - case REACT_MEMO_TYPE: - return getComponentName(type.type); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; try { - return getComponentName(type(innerType)); + return getComponentNameFromType(type(innerType)); } catch (x) {} } return null; } +function getComponentNameFromFiber(fiber) { + var type = fiber.type; + switch (fiber.tag) { + case 24: + return "Cache"; + case 9: + return (type.displayName || "Context") + ".Consumer"; + case 10: + return (type._context.displayName || "Context") + ".Provider"; + case 18: + return "DehydratedFragment"; + case 11: + return ( + (fiber = type.render), + (fiber = fiber.displayName || fiber.name || ""), + type.displayName || + ("" !== fiber ? "ForwardRef(" + fiber + ")" : "ForwardRef") + ); + case 7: + return "Fragment"; + case 5: + return type; + case 4: + return "Portal"; + case 3: + return "Root"; + case 6: + return "Text"; + case 16: + return getComponentNameFromType(type); + case 23: + return "LegacyHidden"; + case 8: + return type === REACT_STRICT_MODE_TYPE ? "StrictMode" : "Mode"; + case 22: + return "Offscreen"; + case 12: + return "Profiler"; + case 21: + return "Scope"; + case 13: + return "Suspense"; + case 19: + return "SuspenseList"; + case 1: + case 0: + case 17: + case 2: + case 14: + case 15: + if ("function" === typeof type) + return type.displayName || type.name || null; + if ("string" === typeof type) return type; + } + return null; +} function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1219,7 +1294,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1307,19 +1382,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1353,7 +1423,7 @@ function restoreDeletedValuesInNestedArray( node, validAttributes ) { - if (Array.isArray(node)) + if (isArrayImpl(node)) for (var i = node.length; i-- && 0 < removedKeyCount; ) restoreDeletedValuesInNestedArray( updatePayload, @@ -1399,9 +1469,9 @@ function diffNestedProperty( : prevProp ? clearNestedProperty(updatePayload, prevProp, validAttributes) : updatePayload; - if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) + if (!isArrayImpl(prevProp) && !isArrayImpl(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); - if (Array.isArray(prevProp) && Array.isArray(nextProp)) { + if (isArrayImpl(prevProp) && isArrayImpl(nextProp)) { var minLength = prevProp.length < nextProp.length ? prevProp.length : nextProp.length, i; @@ -1426,7 +1496,7 @@ function diffNestedProperty( ); return updatePayload; } - return Array.isArray(prevProp) + return isArrayImpl(prevProp) ? diffProperties( updatePayload, ReactNativePrivateInterface.flattenStyle(prevProp), @@ -1442,7 +1512,7 @@ function diffNestedProperty( } function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) return updatePayload; - if (!Array.isArray(nextProp)) + if (!isArrayImpl(nextProp)) return diffProperties( updatePayload, emptyObject, @@ -1459,7 +1529,7 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { } function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) return updatePayload; - if (!Array.isArray(prevProp)) + if (!isArrayImpl(prevProp)) return diffProperties( updatePayload, prevProp, @@ -1569,60 +1639,295 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { }; } var ReactNativeFiberHostComponent = (function() { - function ReactNativeFiberHostComponent(tag, viewConfig) { - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - } - var _proto = ReactNativeFiberHostComponent.prototype; - _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; - _proto.measure = function(callback) { - ReactNativePrivateInterface.UIManager.measure( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureInWindow = function(callback) { - ReactNativePrivateInterface.UIManager.measureInWindow( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - if ("number" === typeof relativeToNativeNode) - var relativeNode = relativeToNativeNode; - else - relativeToNativeNode._nativeTag && - (relativeNode = relativeToNativeNode._nativeTag); - null != relativeNode && - ReactNativePrivateInterface.UIManager.measureLayout( + function ReactNativeFiberHostComponent(tag, viewConfig) { + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + } + var _proto = ReactNativeFiberHostComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + _proto.measure = function(callback) { + ReactNativePrivateInterface.UIManager.measure( this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - _proto.setNativeProps = function(nativeProps) { - nativeProps = diffProperties( - null, - emptyObject, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( + }; + _proto.measureInWindow = function(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - return ReactNativeFiberHostComponent; -})(); + }; + _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + this._nativeTag, + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + _proto.setNativeProps = function(nativeProps) { + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + this.viewConfig.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + this._nativeTag, + this.viewConfig.uiViewClassName, + nativeProps + ); + }; + return ReactNativeFiberHostComponent; + })(), + scheduleCallback = Scheduler.unstable_scheduleCallback, + cancelCallback = Scheduler.unstable_cancelCallback, + shouldYield = Scheduler.unstable_shouldYield, + requestPaint = Scheduler.unstable_requestPaint, + now = Scheduler.unstable_now, + ImmediatePriority = Scheduler.unstable_ImmediatePriority, + UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + NormalPriority = Scheduler.unstable_NormalPriority, + IdlePriority = Scheduler.unstable_IdlePriority, + rendererID = null, + injectedHook = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function onCommitRoot(root, eventPriority) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + var didError = 128 === (root.current.flags & 128); + switch (eventPriority) { + case 1: + var schedulerPriority = ImmediatePriority; + break; + case 4: + schedulerPriority = UserBlockingPriority; + break; + case 16: + schedulerPriority = NormalPriority; + break; + case 536870912: + schedulerPriority = IdlePriority; + break; + default: + schedulerPriority = NormalPriority; + } + injectedHook.onCommitFiberRoot( + rendererID, + root, + schedulerPriority, + didError + ); + } catch (err) {} +} +var nextTransitionLane = 64, + nextRetryLane = 4194304; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return 1; + case 2: + return 2; + case 4: + return 4; + case 8: + return 8; + case 16: + return 16; + case 32: + return 32; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return lanes & 4194240; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return lanes & 130023424; + case 134217728: + return 134217728; + case 268435456: + return 268435456; + case 536870912: + return 536870912; + case 1073741824: + return 1073741824; + default: + return lanes; + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return 0; + var nextLanes = 0, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes, + nonIdlePendingLanes = pendingLanes & 268435455; + if (0 !== nonIdlePendingLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? (nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)) + : ((pingedLanes &= nonIdlePendingLanes), + 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes))); + } else + (nonIdlePendingLanes = pendingLanes & ~suspendedLanes), + 0 !== nonIdlePendingLanes + ? (nextLanes = getHighestPriorityLanes(nonIdlePendingLanes)) + : 0 !== pingedLanes && + (nextLanes = getHighestPriorityLanes(pingedLanes)); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) && + ((suspendedLanes = nextLanes & -nextLanes), + (pingedLanes = wipLanes & -wipLanes), + suspendedLanes >= pingedLanes || + (16 === suspendedLanes && 0 !== (pingedLanes & 4194240))) + ) + return wipLanes; + 0 !== (nextLanes & 4) && (nextLanes |= pendingLanes & 16); + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (pendingLanes = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function computeExpirationTime(lane, currentTime) { + switch (lane) { + case 1: + case 2: + case 4: + return currentTime + 250; + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return currentTime + 5e3; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return -1; + case 134217728: + case 268435456: + case 536870912: + case 1073741824: + return -1; + default: + return -1; + } +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$8 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$8; + remainingLanes[index$8] = 0; + eventTimes[index$8] = -1; + root[index$8] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$9 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$9; + (lane & entangledLanes) | (root[index$9] & entangledLanes) && + (root[index$9] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var currentUpdatePriority = 0; +function lanesToEventPriority(lanes) { + lanes &= -lanes; + return 1 < lanes + ? 4 < lanes + ? 0 !== (lanes & 268435455) + ? 16 + : 536870912 + : 4 + : 1; +} function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." @@ -1671,7 +1976,8 @@ function describeFunctionComponentFrame(fn, source) { ? describeComponentFrame(fn.displayName || fn.name || null, source, null) : ""; } -var valueStack = [], +var hasOwnProperty = Object.prototype.hasOwnProperty, + valueStack = [], index = -1; function createCursor(defaultValue) { return { current: defaultValue }; @@ -1725,13 +2031,13 @@ function pushTopLevelContextObject(fiber, context, didChange) { } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; - fiber = type.childContextTypes; + type = type.childContextTypes; if ("function" !== typeof instance.getChildContext) return parentContext; instance = instance.getChildContext(); for (var contextKey in instance) - if (!(contextKey in fiber)) + if (!(contextKey in type)) throw Error( - (getComponentName(type) || "Unknown") + + (getComponentNameFromFiber(fiber) || "Unknown") + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.' @@ -1767,359 +2073,79 @@ function invalidateContextProvider(workInProgress, type, didChange) { : pop(didPerformWorkStackCursor); push(didPerformWorkStackCursor, didChange); } -var rendererID = null, - injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, - Scheduler_now = Scheduler.unstable_now; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; +var syncQueue = null, + includesLegacySyncCallbacks = !1, + isFlushingSyncQueue = !1; +function flushSyncCallbacks() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0, + previousUpdatePriority = currentUpdatePriority; + try { + var queue = syncQueue; + for (currentUpdatePriority = 1; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + syncQueue = null; + includesLegacySyncCallbacks = !1; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), + error); + } finally { + (currentUpdatePriority = previousUpdatePriority), + (isFlushingSyncQueue = !1); + } } + return null; } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +function is(x, y) { + return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); +} +var objectIs = "function" === typeof Object.is ? Object.is : is; +function shallowEqual(objA, objB) { + if (objectIs(objA, objB)) return !0; + if ( + "object" !== typeof objA || + null === objA || + "object" !== typeof objB || + null === objB + ) + return !1; + var keysA = Object.keys(objA), + keysB = Object.keys(objB); + if (keysA.length !== keysB.length) return !1; + for (keysB = 0; keysB < keysA.length; keysB++) + if ( + !hasOwnProperty.call(objB, keysA[keysB]) || + !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + ) + return !1; + return !0; +} +function describeFiber(fiber) { + switch (fiber.tag) { case 5: - return 97; - case 3: + return describeComponentFrame(fiber.type, null, null); + case 16: + return describeComponentFrame("Lazy", null, null); + case 13: + return describeComponentFrame("Suspense", null, null); + case 19: + return describeComponentFrame("SuspenseList", null, null); + case 0: case 2: + case 15: + return describeFunctionComponentFrame(fiber.type, null); + case 11: + return describeFunctionComponentFrame(fiber.type.render, null); case 1: - return 95; - case 0: - return 90; + return (fiber = describeFunctionComponentFrame(fiber.type, null)), fiber; default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } -} -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; -function is(x, y) { - return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); -} -var objectIs = "function" === typeof Object.is ? Object.is : is, - hasOwnProperty = Object.prototype.hasOwnProperty; -function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; - if ( - "object" !== typeof objA || - null === objA || - "object" !== typeof objB || - null === objB - ) - return !1; - var keysA = Object.keys(objA), - keysB = Object.keys(objB); - if (keysA.length !== keysB.length) return !1; - for (keysB = 0; keysB < keysA.length; keysB++) - if ( - !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) - ) - return !1; - return !0; -} -function describeFiber(fiber) { - switch (fiber.tag) { - case 5: - return describeComponentFrame(fiber.type, null, null); - case 16: - return describeComponentFrame("Lazy", null, null); - case 13: - return describeComponentFrame("Suspense", null, null); - case 19: - return describeComponentFrame("SuspenseList", null, null); - case 0: - case 2: - case 15: - return describeFunctionComponentFrame(fiber.type, null); - case 11: - return describeFunctionComponentFrame(fiber.type.render, null); - case 1: - return (fiber = describeFunctionComponentFrame(fiber.type, null)), fiber; - default: - return ""; + return ""; } } function getStackByFiberInDevAndProd(workInProgress) { @@ -2148,14 +2174,14 @@ function resolveDefaultProps(Component, baseProps) { var valueCursor = createCursor(null), currentlyRenderingFiber = null, lastContextDependency = null, - lastContextWithAllBitsObserved = null; + lastFullyObservedContext = null; function resetContextDependencies() { - lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; + lastFullyObservedContext = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue = currentValue; + context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2175,44 +2201,41 @@ function scheduleWorkOnParentPath(parent, renderLanes) { } function prepareToReadContext(workInProgress, renderLanes) { currentlyRenderingFiber = workInProgress; - lastContextWithAllBitsObserved = lastContextDependency = null; + lastFullyObservedContext = lastContextDependency = null; workInProgress = workInProgress.dependencies; null !== workInProgress && null !== workInProgress.firstContext && (0 !== (workInProgress.lanes & renderLanes) && (didReceiveUpdate = !0), (workInProgress.firstContext = null)); } -function readContext(context, observedBits) { - if ( - lastContextWithAllBitsObserved !== context && - !1 !== observedBits && - 0 !== observedBits - ) { - if ("number" !== typeof observedBits || 1073741823 === observedBits) - (lastContextWithAllBitsObserved = context), (observedBits = 1073741823); - observedBits = { context: context, observedBits: observedBits, next: null }; - if (null === lastContextDependency) { +function readContext(context) { + var value = context._currentValue; + if (lastFullyObservedContext !== context) + if ( + ((context = { context: context, memoizedValue: value, next: null }), + null === lastContextDependency) + ) { if (null === currentlyRenderingFiber) throw 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; + lastContextDependency = context; currentlyRenderingFiber.dependencies = { lanes: 0, - firstContext: observedBits, + firstContext: context, responders: null }; - } else lastContextDependency = lastContextDependency.next = observedBits; - } - return context._currentValue; + } else lastContextDependency = lastContextDependency.next = context; + return value; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2238,14 +2261,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 4194240))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2314,111 +2355,111 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + 0 !== pendingQueue.lane && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2474,7 +2515,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2485,7 +2527,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2495,7 +2538,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2567,7 +2611,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderLanes); instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && @@ -2589,7 +2632,6 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { "function" === typeof instance.componentDidMount && (workInProgress.flags |= 4); } -var isArray = Array.isArray; function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( @@ -2642,25 +2684,22 @@ function coerceRef(returnFiber, current, element) { return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { - if ("textarea" !== returnFiber.type) - throw 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) + - "). If you meant to render a collection of children, use an array instead." - ); + returnFiber = Object.prototype.toString.call(newChild); + throw Error( + "Objects are not valid as a React child (found: " + + ("[object Object]" === returnFiber + ? "object with keys {" + Object.keys(newChild).join(", ") + "}" + : returnFiber) + + "). If you meant to render a collection of children, use an array instead." + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2692,16 +2731,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2716,7 +2755,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2805,7 +2853,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (newChild = createFiberFromFragment( newChild, @@ -2830,22 +2878,14 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key ? updatePortal(returnFiber, oldFiber, newChild, lanes) : null; } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return null !== key ? null : updateFragment(returnFiber, oldFiber, newChild, lanes, null); @@ -2873,15 +2913,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -2892,7 +2924,7 @@ function ChildReconciler(shouldTrackSideEffects) { updatePortal(returnFiber, existingChildren, newChild, lanes) ); } - if (isArray(newChild) || getIteratorFn(newChild)) + if (isArrayImpl(newChild) || getIteratorFn(newChild)) return ( (existingChildren = existingChildren.get(newIdx) || null), updateFragment(returnFiber, existingChildren, newChild, lanes, null) @@ -3075,55 +3107,49 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.type === REACT_FRAGMENT_TYPE && null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); - var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) + if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; + var key = newChild.key; for ( isUnkeyedTopLevelFragment = currentFirstChild; null !== isUnkeyedTopLevelFragment; ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + if (isUnkeyedTopLevelFragment.key === key) { + key = newChild.type; + if (key === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === key) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3199,6 +3225,22 @@ function ChildReconciler(shouldTrackSideEffects) { } return placeSingleChild(returnFiber); } + if (isArrayImpl(newChild)) + return reconcileChildrenArray( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + if (getIteratorFn(newChild)) + return reconcileChildrenIterator( + returnFiber, + currentFirstChild, + newChild, + lanes + ); + throwOnInvalidObjectType(returnFiber, newChild); + } if ("string" === typeof newChild || "number" === typeof newChild) return ( (newChild = "" + newChild), @@ -3217,21 +3259,6 @@ function ChildReconciler(shouldTrackSideEffects) { (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); - if (isArray(newChild)) - return reconcileChildrenArray( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - if (getIteratorFn(newChild)) - return reconcileChildrenIterator( - returnFiber, - currentFirstChild, - newChild, - lanes - ); - isObject && throwOnInvalidObjectType(returnFiber, newChild); if ("undefined" === typeof newChild && !isUnkeyedTopLevelFragment) switch (returnFiber.tag) { case 1: @@ -3239,7 +3266,7 @@ function ChildReconciler(shouldTrackSideEffects) { case 11: case 15: throw Error( - (getComponentName(returnFiber.type) || "Component") + + (getComponentNameFromFiber(returnFiber) || "Component") + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." ); } @@ -3301,7 +3328,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3453,10 +3480,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3481,22 +3509,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3536,7 +3575,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3566,25 +3605,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$13 = 31 - clz32(lanes), - lane = 1 << index$13; - entanglements[index$13] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3611,6 +3638,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3636,6 +3665,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3684,7 +3715,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3692,10 +3723,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(1049600, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3756,19 +3787,18 @@ function updateMemo(nextCreate, deps) { return nextCreate; } function startTransition(setPending, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var prevTransition = ReactCurrentBatchConfig$1.transition; - ReactCurrentBatchConfig$1.transition = 1; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.transition = prevTransition; - } - }); + var previousPriority = currentUpdatePriority; + currentUpdatePriority = + 0 !== previousPriority && 4 > previousPriority ? previousPriority : 4; + setPending(!0); + var prevTransition = ReactCurrentBatchConfig$1.transition; + ReactCurrentBatchConfig$1.transition = 1; + try { + setPending(!1), callback(); + } finally { + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$1.transition = prevTransition); + } } function dispatchAction(fiber, queue, action) { var eventTime = requestEventTime(), @@ -3780,33 +3810,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 4194240) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3863,6 +3915,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3904,7 +3958,7 @@ var ContextOnlyDispatcher = { isPending = _mountState2[0]; _mountState2 = startTransition.bind(null, _mountState2[1]); mountWorkInProgressHook().memoizedState = _mountState2; - return [_mountState2, isPending]; + return [isPending, _mountState2]; }, useMutableSource: function(source, getSnapshot, subscribe) { var hook = mountWorkInProgressHook(); @@ -3953,8 +4007,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = updateReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = updateReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -3995,8 +4050,9 @@ var ContextOnlyDispatcher = { return prevValue; }, useTransition: function() { - var isPending = rerenderReducer(basicStateReducer)[0]; - return [updateWorkInProgressHook().memoizedState, isPending]; + var isPending = rerenderReducer(basicStateReducer)[0], + start = updateWorkInProgressHook().memoizedState; + return [isPending, start]; }, useMutableSource: updateMutableSource, useOpaqueIdentifier: function() { @@ -4053,7 +4109,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4129,14 +4185,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4153,31 +4210,39 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 1)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - markSpawnedWork(1073741824), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, current), - null - ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= nextProps; + } else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4187,7 +4252,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4212,7 +4277,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4372,7 +4437,8 @@ function updateClassComponent( oldState, newState, oldContext - )) + ) || + !1) ? (getDerivedStateFromProps || ("function" !== typeof instance.UNSAFE_componentWillUpdate && "function" !== typeof instance.componentWillUpdate) || @@ -4387,7 +4453,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4395,7 +4461,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4409,7 +4475,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4430,7 +4496,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4478,18 +4544,21 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; +} function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, suspenseContext = suspenseStackCursor.current, showFallback = !1, JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4506,7 +4575,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4518,10 +4589,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432), + (workInProgress.lanes = 4194304), current ); renderLanes = createFiberFromOffscreen( @@ -4547,8 +4619,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4575,8 +4650,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4599,10 +4677,10 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 8 && + workInProgress.mode & 2 && ((progressedPrimaryFragment.actualDuration = 0), (progressedPrimaryFragment.actualStartTime = -1), (progressedPrimaryFragment.selfBaseDuration = 0), @@ -4637,13 +4715,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4653,33 +4732,27 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + var mode = workInProgress.mode; + current = current.child; + var currentFallbackChildFragment = current.sibling, + primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 1) && workInProgress.child !== current ? ((primaryChildren = workInProgress.child), (primaryChildren.childLanes = 0), (primaryChildren.pendingProps = primaryChildProps), - workInProgress.mode & 8 && + workInProgress.mode & 2 && ((primaryChildren.actualDuration = 0), (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration), - (primaryChildren.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration)), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (primaryChildren.selfBaseDuration = current.selfBaseDuration), + (primaryChildren.treeBaseDuration = current.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4704,8 +4777,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4715,16 +4787,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4733,9 +4803,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4758,7 +4828,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4779,8 +4849,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4802,19 +4871,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4825,25 +4886,23 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } - return null; + return workInProgress.child; } var appendAllChildren, updateHostContainer, @@ -4900,89 +4959,153 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (lastTailNode$65.sibling = null); } } -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + if (0 !== (completedWork.mode & 2)) { + for ( + var treeBaseDuration$67 = completedWork.selfBaseDuration, + child$68 = completedWork.child; + null !== child$68; + + ) + (newChildLanes |= child$68.lanes | child$68.childLanes), + (subtreeFlags |= child$68.subtreeFlags & 1835008), + (subtreeFlags |= child$68.flags & 1835008), + (treeBaseDuration$67 += child$68.treeBaseDuration), + (child$68 = child$68.sibling); + completedWork.treeBaseDuration = treeBaseDuration$67; + } else + for ( + treeBaseDuration$67 = completedWork.child; + null !== treeBaseDuration$67; + + ) + (newChildLanes |= + treeBaseDuration$67.lanes | treeBaseDuration$67.childLanes), + (subtreeFlags |= treeBaseDuration$67.subtreeFlags & 1835008), + (subtreeFlags |= treeBaseDuration$67.flags & 1835008), + (treeBaseDuration$67.return = completedWork), + (treeBaseDuration$67 = treeBaseDuration$67.sibling); + else if (0 !== (completedWork.mode & 2)) { + treeBaseDuration$67 = completedWork.actualDuration; + child$68 = completedWork.selfBaseDuration; + for (var child = completedWork.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (subtreeFlags |= child.subtreeFlags), + (subtreeFlags |= child.flags), + (treeBaseDuration$67 += child.actualDuration), + (child$68 += child.treeBaseDuration), + (child = child.sibling); + completedWork.actualDuration = treeBaseDuration$67; + completedWork.treeBaseDuration = child$68; + } else + for ( + treeBaseDuration$67 = completedWork.child; + null !== treeBaseDuration$67; + + ) + (newChildLanes |= + treeBaseDuration$67.lanes | treeBaseDuration$67.childLanes), + (subtreeFlags |= treeBaseDuration$67.subtreeFlags), + (subtreeFlags |= treeBaseDuration$67.flags), + (treeBaseDuration$67.return = completedWork), + (treeBaseDuration$67 = treeBaseDuration$67.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); else { if (!newProps) { if (null === workInProgress.stateNode) throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." ); + bubbleProperties(workInProgress); return null; } requiredContext(contextStackCursor$1.current); current = allocateTag(); - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); ReactNativePrivateInterface.UIManager.createView( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload ); - rootContainerInstance = new ReactNativeFiberHostComponent( + renderLanes = new ReactNativeFiberHostComponent( current, - renderLanes, + type, workInProgress ); instanceCache.set(current, workInProgress); instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 128); + appendAllChildren(renderLanes, workInProgress, !1, !1); + workInProgress.stateNode = renderLanes; + finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5002,32 +5125,32 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "Text strings must be rendered within a component." ); - rootContainerInstance = allocateTag(); + renderLanes = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, + renderLanes, "RCTRawText", current, { text: newProps } ); - instanceCache.set(rootContainerInstance, workInProgress); - workInProgress.stateNode = rootContainerInstance; + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return ( (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 8) && + 0 !== (workInProgress.mode & 2) && transferActualDuration(workInProgress), workInProgress ); newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5042,89 +5165,100 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } - if (newProps || rootContainerInstance) workInProgress.flags |= 4; + if (newProps || renderLanes) workInProgress.flags |= 4; + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 2) && + newProps && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), + (renderLanes = newProps), (updatePayload = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (renderLanes = rootContainerInstance.alternate), - null === renderLanes - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = updatePayload), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null), - (rootContainerInstance.selfBaseDuration = 0), - (rootContainerInstance.treeBaseDuration = 0)) - : ((rootContainerInstance.childLanes = - renderLanes.childLanes), - (rootContainerInstance.lanes = renderLanes.lanes), - (rootContainerInstance.child = renderLanes.child), - (rootContainerInstance.memoizedProps = - renderLanes.memoizedProps), - (rootContainerInstance.memoizedState = - renderLanes.memoizedState), - (rootContainerInstance.updateQueue = - renderLanes.updateQueue), - (rootContainerInstance.type = renderLanes.type), - (updatePayload = renderLanes.dependencies), - (rootContainerInstance.dependencies = + (renderLanes.flags &= 1835010), + (type = renderLanes.alternate), + null === type + ? ((renderLanes.childLanes = 0), + (renderLanes.lanes = updatePayload), + (renderLanes.child = null), + (renderLanes.subtreeFlags = 0), + (renderLanes.memoizedProps = null), + (renderLanes.memoizedState = null), + (renderLanes.updateQueue = null), + (renderLanes.dependencies = null), + (renderLanes.stateNode = null), + (renderLanes.selfBaseDuration = 0), + (renderLanes.treeBaseDuration = 0)) + : ((renderLanes.childLanes = type.childLanes), + (renderLanes.lanes = type.lanes), + (renderLanes.child = type.child), + (renderLanes.subtreeFlags = 0), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = type.memoizedProps), + (renderLanes.memoizedState = type.memoizedState), + (renderLanes.updateQueue = type.updateQueue), + (renderLanes.type = type.type), + (updatePayload = type.dependencies), + (renderLanes.dependencies = null === updatePayload ? null : { lanes: updatePayload.lanes, firstContext: updatePayload.firstContext }), - (rootContainerInstance.selfBaseDuration = - renderLanes.selfBaseDuration), - (rootContainerInstance.treeBaseDuration = - renderLanes.treeBaseDuration)), + (renderLanes.selfBaseDuration = type.selfBaseDuration), + (renderLanes.treeBaseDuration = type.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, @@ -5134,80 +5268,74 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; case 22: case 23: return ( popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), null !== current && - (null !== current.memoizedState) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 1)) || + bubbleProperties(workInProgress), null ); } @@ -5222,9 +5350,9 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 2) && transferActualDuration(workInProgress), workInProgress) : null; @@ -5234,11 +5362,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5246,9 +5374,9 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 2) && transferActualDuration(workInProgress), workInProgress) : null @@ -5258,10 +5386,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5334,212 +5464,214 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$82 = finishedRoot.create; - finishedRoot.destroy = create$82(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$82 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$82; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$82 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$82, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$86 = effect.create; + effect.destroy = create$86(); } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - create$82 = finishedWork.memoizedProps.onRender; - _effect = commitTime; - "function" === typeof create$82 && - create$82( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - _effect, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } function hideOrUnhideAllChildren(finishedWork, isHidden) { - for (var node = finishedWork; ; ) { + for (var hostSubtreeRoot = null, 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 ( - ((22 !== node.tag && 23 !== node.tag) || - null === node.memoizedState || - node === finishedWork) && - null !== node.child - ) { - node.child.return = node; - node = node.child; - continue; + if (null === hostSubtreeRoot) { + hostSubtreeRoot = node; + 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) { + if (null === hostSubtreeRoot) throw Error("Not yet implemented."); + } else if ( + ((22 !== node.tag && 23 !== node.tag) || + null === node.memoizedState || + node === finishedWork) && + 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; + hostSubtreeRoot === node && (hostSubtreeRoot = null); node = node.return; } + hostSubtreeRoot === node && (hostSubtreeRoot = null); node.sibling.return = node.return; node = node.sibling; } } -function commitUnmount(finishedRoot, current) { +function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) try { injectedHook.onCommitFiberUnmount(rendererID, current); @@ -5556,26 +5688,24 @@ function commitUnmount(finishedRoot, current) { ) { var effect = (finishedRoot = finishedRoot.next); do { - var _effect2 = effect, - destroy = _effect2.destroy; - _effect2 = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (_effect2 & 4)) - enqueuePendingPassiveHookEffectUnmount(current, effect); - else { - _effect2 = current; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } + var _effect = effect, + destroy = _effect.destroy; + _effect = _effect.tag; + if (void 0 !== destroy && 0 !== (_effect & 2)) { + _effect = current; + var nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect, nearestMountedAncestor, error); } + } effect = effect.next; } while (effect !== finishedRoot); } break; case 1: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); finishedRoot = current.stateNode; if ("function" === typeof finishedRoot.componentWillUnmount) try { @@ -5583,26 +5713,36 @@ function commitUnmount(finishedRoot, current) { (finishedRoot.state = current.memoizedState), finishedRoot.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError( + current, + nearestMountedAncestor$jscomp$0, + unmountError + ); } break; case 5: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); break; case 4: - unmountHostComponents(finishedRoot, current); + unmountHostComponents( + finishedRoot, + current, + nearestMountedAncestor$jscomp$0 + ); } } -function detachFiberMutation(fiber) { - fiber.alternate = null; +function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; + null !== alternate && + ((fiber.alternate = null), detachFiberAfterEffects(alternate)); fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function isHostParent(fiber) { @@ -5637,7 +5777,7 @@ function commitPlacement(finishedWork) { "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); } - parentFiber.flags & 16 && (parentFiber.flags &= -17); + parentFiber.flags & 32 && (parentFiber.flags &= -33); a: b: for (parentFiber = finishedWork; ; ) { for (; null === parentFiber.sibling; ) { if (null === parentFiber.return || isHostParent(parentFiber.return)) { @@ -5672,10 +5812,9 @@ function commitPlacement(finishedWork) { : insertOrAppendPlacementNode(finishedWork, parentFiber, parent); } function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - if (((node = isHost ? node.stateNode : node.stateNode.instance), before)) { + var tag = node.tag; + if (5 === tag || 6 === tag) + if (((node = node.stateNode), before)) { if ("number" === typeof parent) throw Error("Container does not support insertBefore operation"); } else @@ -5693,58 +5832,57 @@ function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { (node = node.sibling); } function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - (node = isHost ? node.stateNode : node.stateNode.instance), - before - ? ((tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - (before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [before], - [], - [], - [] - )) - : ((before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - ["number" === typeof node ? node : node._nativeTag], - [before], - [] - ))) - : ((before = "number" === typeof node ? node : node._nativeTag), - (tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - tag.push(node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [tag.length - 1], - [], - [], - [] - )) - : (tag.push(node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - [before], - [tag.length - 1], - [] - ))); + var tag = node.tag; + if (5 === tag || 6 === tag) + if (((node = node.stateNode), before)) { + tag = parent._children; + var index = tag.indexOf(node); + 0 <= index + ? (tag.splice(index, 1), + (before = tag.indexOf(before)), + tag.splice(before, 0, node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [index], + [before], + [], + [], + [] + )) + : ((before = tag.indexOf(before)), + tag.splice(before, 0, node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + ["number" === typeof node ? node : node._nativeTag], + [before], + [] + )); + } else + (before = "number" === typeof node ? node : node._nativeTag), + (tag = parent._children), + (index = tag.indexOf(node)), + 0 <= index + ? (tag.splice(index, 1), + tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [index], + [tag.length - 1], + [], + [], + [] + )) + : (tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + [before], + [tag.length - 1], + [] + )); else if (4 !== tag && ((node = node.child), null !== node)) for ( insertOrAppendPlacementNode(node, before, parent), node = node.sibling; @@ -5753,7 +5891,11 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents(finishedRoot$jscomp$0, current) { +function unmountHostComponents( + finishedRoot$jscomp$0, + current, + nearestMountedAncestor$jscomp$0 +) { for ( var node = current, currentParentIsValid = !1, @@ -5791,12 +5933,13 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { a: for ( var finishedRoot = finishedRoot$jscomp$0, root = node, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0, node$jscomp$0 = root; ; ) if ( - (commitUnmount(finishedRoot, node$jscomp$0), + (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) ) (node$jscomp$0.child.return = node$jscomp$0), @@ -5823,18 +5966,18 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { [0] )) : ((finishedRoot = currentParent), - (node$jscomp$0 = node.stateNode), - recursivelyUncacheFiberNode(node$jscomp$0), + (nearestMountedAncestor = node.stateNode), + recursivelyUncacheFiberNode(nearestMountedAncestor), (root = finishedRoot._children), - (node$jscomp$0 = root.indexOf(node$jscomp$0)), - root.splice(node$jscomp$0, 1), + (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), + root.splice(nearestMountedAncestor, 1), ReactNativePrivateInterface.UIManager.manageChildren( finishedRoot._nativeTag, [], [], [], [], - [node$jscomp$0] + [nearestMountedAncestor] )); } else if (4 === node.tag) { if (null !== node.child) { @@ -5845,7 +5988,12 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { continue; } } else if ( - (commitUnmount(finishedRoot$jscomp$0, node), null !== node.child) + (commitUnmount( + finishedRoot$jscomp$0, + node, + nearestMountedAncestor$jscomp$0 + ), + null !== node.child) ) { node.child.return = node; node = node.child; @@ -5867,42 +6015,31 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do - 3 === (effect.tag & 3) && - ((finishedWork = effect.destroy), - (effect.destroy = void 0), - void 0 !== finishedWork && finishedWork()), - (effect = effect.next); - while (effect !== updateQueue); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 1: return; case 5: - updateQueue = finishedWork.stateNode; - if (null != updateQueue) { - effect = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : effect; + var instance = finishedWork.stateNode; + if (null != instance) { + var newProps = finishedWork.memoizedProps; + current = null !== current ? current.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && - ((finishedWork = updateQueue.viewConfig), - instanceProps.set(updateQueue._nativeTag, effect), - (effect = diffProperties( + ((finishedWork = instance.viewConfig), + instanceProps.set(instance._nativeTag, newProps), + (newProps = diffProperties( null, current, - effect, + newProps, finishedWork.validAttributes )), - null != effect && + null != newProps && ReactNativePrivateInterface.UIManager.updateView( - updateQueue._nativeTag, + instance._nativeTag, finishedWork.uiViewClassName, - effect + newProps )); } return; @@ -5954,24 +6091,205 @@ function attachSuspenseRetryListeners(finishedWork) { wakeables.forEach(function(wakeable) { var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); retryCache.has(wakeable) || - (!0 !== wakeable.__reactDoNotTraceInteractions && - (retry = tracing.unstable_wrap(retry)), - retryCache.add(wakeable), - wakeable.then(retry, retry)); + (retryCache.add(wakeable), wakeable.then(retry, retry)); }); } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; +function commitMutationEffects(root, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + firstChild = nextEffect; + var deletions = firstChild.deletions; + if (null !== deletions) + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; + try { + unmountHostComponents(root, childToDelete, firstChild); + var alternate = childToDelete.alternate; + null !== alternate && (alternate.return = null); + childToDelete.return = null; + } catch (error) { + captureCommitPhaseError(childToDelete, firstChild, error); + } + } + deletions = firstChild.child; + if (0 !== (firstChild.subtreeFlags & 6454) && null !== deletions) + (deletions.return = firstChild), (nextEffect = deletions); + else + for (; null !== nextEffect; ) { + firstChild = nextEffect; + try { + var flags = firstChild.flags; + if (flags & 256) { + var current = firstChild.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + commitPlacement(firstChild); + firstChild.flags &= -3; + break; + case 6: + commitPlacement(firstChild); + firstChild.flags &= -3; + commitWork(firstChild.alternate, firstChild); + break; + case 2048: + firstChild.flags &= -2049; + break; + case 2052: + firstChild.flags &= -2049; + commitWork(firstChild.alternate, firstChild); + break; + case 4: + commitWork(firstChild.alternate, firstChild); + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + deletions = firstChild.sibling; + if (null !== deletions) { + deletions.return = firstChild.return; + nextEffect = deletions; + break; + } + nextEffect = firstChild.return; + } + } +} +function commitLayoutEffects(finishedWork) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; + try { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, firstChild); + break; + case 1: + var instance = firstChild.stateNode; + if (firstChild.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + firstChild.elementType === firstChild.type + ? current.memoizedProps + : resolveDefaultProps( + firstChild.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = firstChild.updateQueue; + null !== updateQueue && + commitUpdateQueue(firstChild, updateQueue, instance); + break; + case 3: + var updateQueue$87 = firstChild.updateQueue; + if (null !== updateQueue$87) { + var instance$88 = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { + case 5: + instance$88 = firstChild.child.stateNode; + break; + case 1: + instance$88 = firstChild.child.stateNode; + } + commitUpdateQueue(firstChild, updateQueue$87, instance$88); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = firstChild.memoizedProps.onRender; + instance$88 = commitTime; + current = null === current ? "mount" : "update"; + "function" === typeof onRender && + onRender( + firstChild.memoizedProps.id, + current, + firstChild.actualDuration, + firstChild.treeBaseDuration, + firstChild.actualStartTime, + instance$88 + ); + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (firstChild.flags & 256) { + instance$88 = void 0; + var ref = firstChild.ref; + if (null !== ref) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { + case 5: + instance$88 = instance$jscomp$0; + break; + default: + instance$88 = instance$jscomp$0; + } + "function" === typeof ref + ? ref(instance$88) + : (ref.current = instance$88); + } + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + } + if (firstChild === fiber) { + nextEffect = null; + break; + } + instance$88 = firstChild.sibling; + if (null !== instance$88) { + instance$88.return = firstChild.return; + nextEffect = instance$88; + break; + } + nextEffect = firstChild.return; + } + } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig, executionContext = 0, workInProgressRoot = null, workInProgress = null, @@ -5980,66 +6298,41 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, - pendingPassiveEffectsRenderPriority = 90, pendingPassiveEffectsLanes = 0, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], - rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, - spawnedWorkDuringRender = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { - return 0 !== (executionContext & 48) + return 0 !== (executionContext & 24) ? now() : -1 !== currentEventTime ? currentEventTime : (currentEventTime = now()); } function requestUpdateLane(fiber) { - fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } - fiber = getCurrentPriorityLevel(); - 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) - : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); - return fiber; + if (0 === (fiber.mode & 1)) return 1; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 4194240) && (nextTransitionLane = 64), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); + fiber = currentUpdatePriority; + return 0 !== fiber ? fiber : 16; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { if (50 < nestedUpdateCount) @@ -6048,30 +6341,23 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { 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 = markUpdateLaneFromFiberToRoot(fiber, lane); - if (null === fiber) return null; - markRootUpdated(fiber, lane, eventTime); - fiber === workInProgressRoot && + var root = markUpdateLaneFromFiberToRoot(fiber, lane); + if (null === root) return null; + markRootUpdated(root, lane, eventTime); + root === workInProgressRoot && ((workInProgressRootUpdatedLanes |= lane), 4 === workInProgressRootExitStatus && - markRootSuspended$1(fiber, workInProgressRootRenderLanes)); - var priorityLevel = getCurrentPriorityLevel(); + markRootSuspended$1(root, workInProgressRootRenderLanes)); 1 === lane - ? 0 !== (executionContext & 8) && 0 === (executionContext & 48) - ? (schedulePendingInteractions(fiber, lane), performSyncWorkOnRoot(fiber)) - : (ensureRootIsScheduled(fiber, eventTime), - schedulePendingInteractions(fiber, lane), + ? 0 !== (executionContext & 4) && 0 === (executionContext & 24) + ? performSyncWorkOnRoot(root) + : (ensureRootIsScheduled(root, eventTime), 0 === executionContext && + 0 === (fiber.mode & 1) && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue())) - : (0 === (executionContext & 4) || - (98 !== priorityLevel && 99 !== priorityLevel) || - (null === rootsWithPendingDiscreteUpdates - ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) - : rootsWithPendingDiscreteUpdates.add(fiber)), - ensureRootIsScheduled(fiber, eventTime), - schedulePendingInteractions(fiber, lane)); - mostRecentlyUpdatedRoot = fiber; + includesLegacySyncCallbacks && flushSyncCallbacks())) + : ensureRootIsScheduled(root, eventTime); + return root; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6096,21 +6382,12 @@ function ensureRootIsScheduled(root, currentTime) { 0 < lanes; ) { - var index$7 = 31 - clz32(lanes), - lane = 1 << index$7, - expirationTime = expirationTimes[index$7]; + var index$6 = 31 - clz32(lanes), + lane = 1 << index$6, + expirationTime = expirationTimes[index$6]; if (-1 === expirationTime) { - if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { - expirationTime = currentTime; - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; - expirationTimes[index$7] = - 10 <= priority - ? expirationTime + 250 - : 6 <= priority - ? expirationTime + 5e3 - : -1; - } + if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) + expirationTimes[index$6] = computeExpirationTime(lane, currentTime); } else expirationTime <= currentTime && (root.expiredLanes |= lane); lanes &= ~lane; } @@ -6118,94 +6395,106 @@ function ensureRootIsScheduled(root, currentTime) { root, root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); - currentTime = return_highestLanePriority; if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode), + null !== existingCallbackNode && cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); + (root.callbackPriority = 0); + else if ( + ((currentTime = suspendedLanes & -suspendedLanes), + root.callbackPriority !== currentTime) + ) { + null != existingCallbackNode && cancelCallback(existingCallbackNode); + if (1 === currentTime) + 0 === root.tag + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + (includesLegacySyncCallbacks = !0), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)) + : ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? (syncQueue = [existingCallbackNode]) + : syncQueue.push(existingCallbackNode)), + scheduleCallback(ImmediatePriority, flushSyncCallbacks), + (existingCallbackNode = null); + else { + switch (lanesToEventPriority(suspendedLanes)) { + case 1: + existingCallbackNode = ImmediatePriority; + break; + case 4: + existingCallbackNode = UserBlockingPriority; + break; + case 16: + existingCallbackNode = NormalPriority; + break; + case 536870912: + existingCallbackNode = IdlePriority; + break; + default: + existingCallbackNode = NormalPriority; + } + existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ); } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); root.callbackPriority = currentTime; root.callbackNode = existingCallbackNode; } } -function performConcurrentWorkOnRoot(root) { +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; - if (0 !== (executionContext & 48)) + currentEventTransitionLane = 0; + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; - if (flushPassiveEffects() && root.callbackNode !== originalCallbackNode) - return null; - var lanes = getNextLanes( - root, - root === workInProgressRoot ? workInProgressRootRenderLanes : 0 - ); - if (0 === lanes) return null; - var lanes$jscomp$0 = lanes; - var exitStatus = executionContext; - executionContext |= 16; - var prevDispatcher = pushDispatcher(); - if ( - workInProgressRoot !== root || - workInProgressRootRenderLanes !== lanes$jscomp$0 - ) - (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, lanes$jscomp$0), - startWorkOnPendingInteractions(root, lanes$jscomp$0); - lanes$jscomp$0 = pushInteractions(root); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = lanes$jscomp$0; - ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = exitStatus; - null !== workInProgress - ? (exitStatus = 0) - : ((workInProgressRoot = null), - (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && - ((executionContext |= 64), + if (flushPassiveEffects() && root.callbackNode !== originalCallbackNode) + return null; + var lanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes : 0 + ); + if (0 === lanes) return null; + var JSCompiler_inline_result = + 0 !== (lanes & root.expiredLanes) ? !1 : 0 === (lanes & 30); + if (JSCompiler_inline_result && !didTimeout) { + didTimeout = lanes; + JSCompiler_inline_result = executionContext; + executionContext |= 8; + var prevDispatcher = pushDispatcher(); + if ( + workInProgressRoot !== root || + workInProgressRootRenderLanes !== didTimeout + ) + (workInProgressRootRenderTargetTime = now() + 500), + prepareFreshStack(root, didTimeout); + do + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + ReactCurrentDispatcher$2.current = prevDispatcher; + executionContext = JSCompiler_inline_result; + null !== workInProgress + ? (didTimeout = 0) + : ((workInProgressRoot = null), + (workInProgressRootRenderLanes = 0), + (didTimeout = workInProgressRootExitStatus)); + } else didTimeout = renderRootSync(root, lanes); + if (0 !== didTimeout) { + 2 === didTimeout && + ((executionContext |= 32), root.hydrate && (root.hydrate = !1), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + (JSCompiler_inline_result = getLanesToRetrySynchronouslyOnError(root)), + 0 !== JSCompiler_inline_result && + ((lanes = JSCompiler_inline_result), + (didTimeout = renderRootSync(root, JSCompiler_inline_result)))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6213,7 +6502,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6223,20 +6512,20 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 130023424) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; - prevDispatcher = root.suspendedLanes; - if ((prevDispatcher & lanes) !== lanes) { + JSCompiler_inline_result = root.suspendedLanes; + if ((JSCompiler_inline_result & lanes) !== lanes) { requestEventTime(); - root.pingedLanes |= root.suspendedLanes & prevDispatcher; + root.pingedLanes |= root.suspendedLanes & JSCompiler_inline_result; break; } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -6244,16 +6533,17 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; - for (prevDispatcher = -1; 0 < lanes; ) { - var index$6 = 31 - clz32(lanes); - lanes$jscomp$0 = 1 << index$6; - index$6 = exitStatus[index$6]; - index$6 > prevDispatcher && (prevDispatcher = index$6); - lanes &= ~lanes$jscomp$0; + if ((lanes & 4194240) === lanes) break; + didTimeout = root.eventTimes; + for (JSCompiler_inline_result = -1; 0 < lanes; ) { + var index$5 = 31 - clz32(lanes); + prevDispatcher = 1 << index$5; + index$5 = didTimeout[index$5]; + index$5 > JSCompiler_inline_result && + (JSCompiler_inline_result = index$5); + lanes &= ~prevDispatcher; } - lanes = prevDispatcher; + lanes = JSCompiler_inline_result; lanes = now() - lanes; lanes = (120 > lanes @@ -6296,33 +6586,26 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$11 = 31 - clz32(suspendedLanes), - lane = 1 << index$11; - root[index$11] = -1; + var index$7 = 31 - clz32(suspendedLanes), + lane = 1 << index$7; + root[index$7] = -1; suspendedLanes &= ~lane; } } function performSyncWorkOnRoot(root) { - if (0 !== (executionContext & 48)) + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( - root === workInProgressRoot && - 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); - 0 !== root.tag && - 2 === exitStatus && - ((executionContext |= 64), - root.hydrate && (root.hydrate = !1), - (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + var lanes = getNextLanes(root, 0); + if (0 === (lanes & 1)) return ensureRootIsScheduled(root, now()), null; + var exitStatus = renderRootSync(root, lanes); + if (0 !== root.tag && 2 === exitStatus) { + executionContext |= 32; + root.hydrate && (root.hydrate = !1); + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + 0 !== errorRetryLanes && + ((lanes = errorRetryLanes), (exitStatus = renderRootSync(root, lanes))); + } if (1 === exitStatus) throw ((exitStatus = workInProgressRootFatalError), prepareFreshStack(root, 0), @@ -6335,11 +6618,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6379,7 +6657,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6389,11 +6667,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; - spawnedWorkDuringRender = null; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6423,7 +6719,7 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress = null; break; } - erroredWork.mode & 8 && + erroredWork.mode & 2 && stopProfilerTimerIfRunningAndRecordDelta(erroredWork, !0); a: { var root = root$jscomp$0, @@ -6431,15 +6727,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6450,15 +6749,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$77 = returnFiber; + workInProgress$81 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { - var nextState = workInProgress$77.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$81.tag)) { + var nextState = workInProgress$81.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$77.memoizedProps; + var props = workInProgress$81.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6470,16 +6769,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$77.updateQueue; + var wakeables = workInProgress$81.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$77.updateQueue = updateQueue; + workInProgress$81.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$77.mode & 2)) { - workInProgress$77.flags |= 64; + if ( + 0 === (workInProgress$81.mode & 1) && + workInProgress$81 !== returnFiber + ) { + workInProgress$81.flags |= 128; sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6510,61 +6812,61 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$77.flags |= 8192; - workInProgress$77.lanes = thrownValue; + workInProgress$81.flags |= 16384; + workInProgress$81.lanes = thrownValue; break a; } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$81 = workInProgress$81.return; + } while (null !== workInProgress$81); value = Error( - (getComponentName(sourceFiber.type) || "A React component") + + (getComponentNameFromFiber(sourceFiber) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." ); } 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$77 = returnFiber; + workInProgress$81 = returnFiber; do { - switch (workInProgress$77.tag) { + switch (workInProgress$81.tag) { case 3: root = value; - workInProgress$77.flags |= 8192; + workInProgress$81.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$78 = createRootErrorUpdate( - workInProgress$77, + workInProgress$81.lanes |= thrownValue; + var update$82 = createRootErrorUpdate( + workInProgress$81, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$78); + enqueueCapturedUpdate(workInProgress$81, update$82); break a; case 1: root = value; - var ctor = workInProgress$77.type, - instance = workInProgress$77.stateNode; + var ctor = workInProgress$81.type, + instance = workInProgress$81.stateNode; if ( - 0 === (workInProgress$77.flags & 64) && + 0 === (workInProgress$81.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$77.flags |= 8192; + workInProgress$81.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$81 = createClassErrorUpdate( - workInProgress$77, + workInProgress$81.lanes |= thrownValue; + var update$85 = createClassErrorUpdate( + workInProgress$81, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$81); + enqueueCapturedUpdate(workInProgress$81, update$85); break a; } } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$81 = workInProgress$81.return; + } while (null !== workInProgress$81); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6582,18 +6884,12 @@ function pushDispatcher() { ReactCurrentDispatcher$2.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } -function pushInteractions(root) { - var prevInteractions = tracing.__interactionsRef.current; - tracing.__interactionsRef.current = root.memoizedInteractions; - return prevInteractions; -} function renderRootSync(root, lanes) { var prevExecutionContext = executionContext; - executionContext |= 16; + executionContext |= 8; var prevDispatcher = pushDispatcher(); - if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) - prepareFreshStack(root, lanes), startWorkOnPendingInteractions(root, lanes); - lanes = pushInteractions(root); + (workInProgressRoot === root && workInProgressRootRenderLanes === lanes) || + prepareFreshStack(root, lanes); do try { workLoopSync(); @@ -6603,7 +6899,6 @@ function renderRootSync(root, lanes) { } while (1); resetContextDependencies(); - tracing.__interactionsRef.current = lanes; executionContext = prevExecutionContext; ReactCurrentDispatcher$2.current = prevDispatcher; if (null !== workInProgress) @@ -6618,12 +6913,12 @@ function workLoopSync() { for (; null !== workInProgress; ) performUnitOfWork(workInProgress); } function workLoopConcurrent() { - for (; null !== workInProgress && !Scheduler_shouldYield(); ) + for (; null !== workInProgress && !shouldYield(); ) performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 8) + 0 !== (unitOfWork.mode & 2) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current = beginWork$1(current, unitOfWork, subtreeRenderLanes)), @@ -6640,8 +6935,8 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - if (0 === (completedWork.mode & 8)) + if (0 === (completedWork.flags & 8192)) { + if (0 === (completedWork.mode & 2)) current = completeWork(current, completedWork, subtreeRenderLanes); else { var fiber = completedWork; @@ -6654,65 +6949,14 @@ function completeUnitOfWork(unitOfWork) { workInProgress = current; return; } - current = completedWork; - if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) - ) { - fiber = 0; - if (0 !== (current.mode & 8)) { - for ( - var actualDuration = current.actualDuration, - treeBaseDuration = current.selfBaseDuration, - shouldBubbleActualDurations = - null === current.alternate || - current.child !== current.alternate.child, - child = current.child; - null !== child; - - ) - (fiber |= child.lanes | child.childLanes), - shouldBubbleActualDurations && - (actualDuration += child.actualDuration), - (treeBaseDuration += child.treeBaseDuration), - (child = child.sibling); - 13 === current.tag && - null !== current.memoizedState && - ((shouldBubbleActualDurations = current.child), - null !== shouldBubbleActualDurations && - (treeBaseDuration -= - shouldBubbleActualDurations.treeBaseDuration)); - current.actualDuration = actualDuration; - current.treeBaseDuration = treeBaseDuration; - } else - for (actualDuration = current.child; null !== actualDuration; ) - (fiber |= actualDuration.lanes | actualDuration.childLanes), - (actualDuration = actualDuration.sibling); - current.childLanes = fiber; - } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } - if (0 !== (completedWork.mode & 8)) { + if (0 !== (completedWork.mode & 2)) { stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1); current = completedWork.actualDuration; for (fiber = completedWork.child; null !== fiber; ) @@ -6720,8 +6964,9 @@ function completeUnitOfWork(unitOfWork) { completedWork.actualDuration = current; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6733,14 +6978,22 @@ function completeUnitOfWork(unitOfWork) { 0 === workInProgressRootExitStatus && (workInProgressRootExitStatus = 5); } function commitRoot(root) { - var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + var previousUpdateLanePriority = currentUpdatePriority, + prevTransition = ReactCurrentBatchConfig$2.transition; + try { + (ReactCurrentBatchConfig$2.transition = 0), + (currentUpdatePriority = 1), + commitRootImpl(root, previousUpdateLanePriority); + } finally { + (ReactCurrentBatchConfig$2.transition = prevTransition), + (currentUpdatePriority = previousUpdateLanePriority); + } return null; } function commitRootImpl(root, renderPriorityLevel) { do flushPassiveEffects(); while (null !== rootWithPendingPassiveEffects); - if (0 !== (executionContext & 48)) + if (0 !== (executionContext & 24)) throw Error("Should not already be working."); var finishedWork = root.finishedWork, lanes = root.finishedLanes; @@ -6752,303 +7005,208 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$12 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$12; - remainingLanes$jscomp$0[index$12] = 0; - eventTimes[index$12] = -1; - expirationTimes[index$12] = -1; - noLongerPendingLanes &= ~lane; - } - null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && - rootsWithPendingDiscreteUpdates.has(root) && - rootsWithPendingDiscreteUpdates.delete(root); + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; - executionContext |= 32; - eventTimes = pushInteractions(root); - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { + remainingLanes = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = 0; + var previousPriority = currentUpdatePriority; + currentUpdatePriority = 1; + var prevExecutionContext = executionContext; + executionContext |= 16; + ReactCurrentOwner$2.current = null; + commitBeforeMutationEffects(root, finishedWork); commitTime = now$1(); - nextEffect = remainingLanes; - do - try { - for (expirationTimes = root; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - break; - case 6: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - noLongerPendingLanes = nextEffect; - unmountHostComponents(expirationTimes, noLongerPendingLanes); - var alternate = noLongerPendingLanes.alternate; - detachFiberMutation(noLongerPendingLanes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$91) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$91); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); + commitMutationEffects(root, finishedWork); root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance; - break; - default: - current = instance; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$92) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$92); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; + commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - tracing.__interactionsRef.current = eventTimes; - executionContext = remainingLanes$jscomp$0; + executionContext = prevExecutionContext; + currentUpdatePriority = previousPriority; + ReactCurrentBatchConfig$2.transition = remainingLanes; } else (root.current = finishedWork), (commitTime = now$1()); - if ((flags$jscomp$0 = rootDoesHavePassiveEffects)) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsLanes = lanes), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (ref = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((instance = nextEffect), - (instance.sibling = null), - (instance.stateNode = null)), - (nextEffect = ref); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsLanes = lanes)); remainingLanes = root.pendingLanes; - if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) - for ( - ref = spawnedWorkDuringRender, - spawnedWorkDuringRender = null, - instance = 0; - instance < ref.length; - instance++ - ) - scheduleInteractions(root, ref[instance], root.memoizedInteractions); - schedulePendingInteractions(root, remainingLanes); - } else legacyErrorBoundariesThatAlreadyFailed = null; - flags$jscomp$0 || finishPendingInteractions(root, lanes); - 1 === remainingLanes + 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - renderPriorityLevel, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), (root = firstUncaughtError), (firstUncaughtError = null), root); - if (0 !== (executionContext & 8)) return null; - flushSyncCallbackQueue(); + if (0 !== (executionContext & 4)) return null; + 0 !== (pendingPassiveEffectsLanes & 1) && + 0 !== root.tag && + flushPassiveEffects(); + flushSyncCallbacks(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { - if (90 !== pendingPassiveEffectsRenderPriority) { - var priorityLevel = - 97 < pendingPassiveEffectsRenderPriority - ? 97 - : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = 90; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); - } - return !1; -} -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function flushPassiveEffectsImpl() { - if (null === rootWithPendingPassiveEffects) return !1; - var root = rootWithPendingPassiveEffects, - lanes = pendingPassiveEffectsLanes; - rootWithPendingPassiveEffects = null; - pendingPassiveEffectsLanes = 0; - if (0 !== (executionContext & 48)) - throw Error("Cannot flush passive effects while already rendering."); - var prevExecutionContext = executionContext; - executionContext |= 32; - var prevInteractions = pushInteractions(root), - unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$97 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$97.destroy; - effect$97.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); - } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$97 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; + if (null !== rootWithPendingPassiveEffects) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes), + prevTransition = ReactCurrentBatchConfig$2.transition, + previousPriority = currentUpdatePriority; try { - var create$101 = effect$97.create; - effect$97.destroy = create$101(); - } catch (error$102) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$102); + ReactCurrentBatchConfig$2.transition = 0; + currentUpdatePriority = 16 > renderPriority ? 16 : renderPriority; + if (null === rootWithPendingPassiveEffects) + var JSCompiler_inline_result = !1; + else { + renderPriority = rootWithPendingPassiveEffects; + rootWithPendingPassiveEffects = null; + pendingPassiveEffectsLanes = 0; + if (0 !== (executionContext & 24)) + throw Error("Cannot flush passive effects while already rendering."); + var prevExecutionContext = executionContext; + executionContext |= 16; + for (nextEffect = renderPriority.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + var sibling = fiber$jscomp$0.sibling, + returnFiber = fiber$jscomp$0.return; + if (fiber$jscomp$0 === fiberToDelete) { + detachFiberAfterEffects(fiber$jscomp$0); + nextEffect = null; + break; + } + if (null !== sibling) { + sibling.return = returnFiber; + nextEffect = sibling; + break; + } + nextEffect = returnFiber; + } + } + } + var previousFiber = fiber.alternate; + if (null !== previousFiber) { + var detachedChild = previousFiber.child; + if (null !== detachedChild) { + previousFiber.child = null; + do { + var detachedSibling = detachedChild.sibling; + detachedChild.sibling = null; + detachedChild = detachedSibling; + } while (null !== detachedChild); + } + } + nextEffect = fiber; + } + } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + b: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + var sibling$jscomp$0 = fiber.sibling; + if (null !== sibling$jscomp$0) { + sibling$jscomp$0.return = fiber.return; + nextEffect = sibling$jscomp$0; + break b; + } + nextEffect = fiber.return; + } + } + var finishedWork = renderPriority.current; + for (nextEffect = finishedWork; null !== nextEffect; ) { + child = nextEffect; + var firstChild = child.child; + if (0 !== (child.subtreeFlags & 1040) && null !== firstChild) + (firstChild.return = child), (nextEffect = firstChild); + else + b: for (child = finishedWork; null !== nextEffect; ) { + deletions = nextEffect; + if (0 !== (deletions.flags & 1024)) + try { + switch (deletions.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, deletions); + } + } catch (error) { + captureCommitPhaseError(deletions, deletions.return, error); + } + if (deletions === child) { + nextEffect = null; + break b; + } + var sibling$jscomp$1 = deletions.sibling; + if (null !== sibling$jscomp$1) { + sibling$jscomp$1.return = deletions.return; + nextEffect = sibling$jscomp$1; + break b; + } + nextEffect = deletions.return; + } + } + executionContext = prevExecutionContext; + flushSyncCallbacks(); + if ( + injectedHook && + "function" === typeof injectedHook.onPostCommitFiberRoot + ) + try { + injectedHook.onPostCommitFiberRoot(rendererID, renderPriority); + } catch (err) {} + JSCompiler_inline_result = !0; + } + return JSCompiler_inline_result; + } finally { + (currentUpdatePriority = previousPriority), + (ReactCurrentBatchConfig$2.transition = prevTransition); } } - for (unmountEffects = root.current.firstEffect; null !== unmountEffects; ) - (create$101 = unmountEffects.nextEffect), - (unmountEffects.nextEffect = null), - unmountEffects.flags & 8 && - ((unmountEffects.sibling = null), (unmountEffects.stateNode = null)), - (unmountEffects = create$101); - tracing.__interactionsRef.current = prevInteractions; - finishPendingInteractions(root, lanes); - executionContext = prevExecutionContext; - flushSyncCallbackQueue(); - return !0; + return !1; } function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { sourceFiber = createCapturedValue(error, sourceFiber); @@ -7058,46 +7216,52 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { rootFiber = markUpdateLaneFromFiberToRoot(rootFiber, 1); null !== rootFiber && (markRootUpdated(rootFiber, 1, sourceFiber), - ensureRootIsScheduled(rootFiber, sourceFiber), - schedulePendingInteractions(rootFiber, 1)); + ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update), - schedulePendingInteractions(fiber, 1); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -7109,34 +7273,28 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 130023424) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) : (workInProgressRootPingedLanes |= pingedLanes)); ensureRootIsScheduled(root, wakeable); - schedulePendingInteractions(root, pingedLanes); } function resolveRetryWakeable(boundaryFiber, wakeable) { var retryCache = boundaryFiber.stateNode; null !== retryCache && retryCache.delete(wakeable); wakeable = 0; 0 === wakeable && - ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + (0 === (boundaryFiber.mode & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) - ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 130023424) && (nextRetryLane = 4194304))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && (markRootUpdated(boundaryFiber, wakeable, retryCache), - ensureRootIsScheduled(boundaryFiber, retryCache), - schedulePendingInteractions(boundaryFiber, wakeable)); + ensureRootIsScheduled(boundaryFiber, retryCache)); } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { @@ -7147,85 +7305,87 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateLanes; - break; - case 12: - 0 !== (renderLanes & workInProgress.childLanes) && - (workInProgress.flags |= 4); - updateLanes = workInProgress.stateNode; - updateLanes.effectDuration = 0; - updateLanes.passiveEffectDuration = 0; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, + if (0 === (renderLanes & updateLanes)) { + didReceiveUpdate = !1; + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer( workInProgress, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + break; + case 10: + updateLanes = workInProgress.type._context; + var nextValue = workInProgress.memoizedProps.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = nextValue; + break; + case 12: + 0 !== (renderLanes & workInProgress.childLanes) && + (workInProgress.flags |= 4); + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( + current, + workInProgress, + renderLanes + ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); + return null !== workInProgress ? workInProgress.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; + case 19: + updateLanes = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; + } + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); + } + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7237,22 +7397,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7262,21 +7422,13 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; - "function" === typeof getDerivedStateFromProps && - applyDerivedStateFromProps( - workInProgress, - updateLanes, - getDerivedStateFromProps, - current - ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7288,28 +7440,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7318,7 +7470,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7327,7 +7479,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7336,8 +7488,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7345,7 +7497,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7353,32 +7505,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7389,19 +7541,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7441,16 +7592,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7477,9 +7628,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 12: return ( (workInProgress.flags |= 4), - (updateLanes = workInProgress.stateNode), - (updateLanes.effectDuration = 0), - (updateLanes.passiveEffectDuration = 0), reconcileChildren( current, workInProgress, @@ -7491,27 +7639,15 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; - getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue); - context$jscomp$0._currentValue = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + nextValue = workInProgress.pendingProps; + hasContext = workInProgress.memoizedProps; + var newValue = nextValue.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = newValue; + if (null !== hasContext) + if (objectIs(hasContext.value, newValue)) { if ( - getDerivedStateFromProps.children === context.children && + hasContext.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7523,76 +7659,71 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + newValue = workInProgress.child, + null !== newValue && (newValue.return = workInProgress); + null !== newValue; ) { - var list = context$jscomp$0.dependencies; + var list = newValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + hasContext = newValue.child; for ( var dependency = list.firstContext; null !== dependency; ) { - if ( - dependency.context === updateLanes && - 0 !== (dependency.observedBits & hasContext) - ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (dependency.context === updateLanes) { + if (1 === newValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = newValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + newValue.lanes |= renderLanes; + dependency = newValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(newValue.return, renderLanes); list.lanes |= renderLanes; break; } dependency = dependency.next; } } else - getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + hasContext = + 10 === newValue.tag + ? newValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; - if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + : newValue.child + : newValue.child; + if (null !== hasContext) hasContext.return = newValue; else - for ( - getDerivedStateFromProps = context$jscomp$0; - null !== getDerivedStateFromProps; - - ) { - if (getDerivedStateFromProps === workInProgress) { - getDerivedStateFromProps = null; + for (hasContext = newValue; null !== hasContext; ) { + if (hasContext === workInProgress) { + hasContext = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + newValue = hasContext.sibling; + if (null !== newValue) { + newValue.return = hasContext.return; + hasContext = newValue; break; } - getDerivedStateFromProps = getDerivedStateFromProps.return; + hasContext = hasContext.return; } - context$jscomp$0 = getDerivedStateFromProps; + newValue = hasContext; } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7600,28 +7731,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), - (hasContext = workInProgress.pendingProps), - (updateLanes = hasContext.children), + (nextValue = workInProgress.type), + (updateLanes = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7639,11 +7769,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7653,8 +7783,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7677,93 +7807,6 @@ beginWork$1 = function(current, workInProgress, renderLanes) { "). This error is likely caused by a bug in React. Please file an issue." ); }; -function markSpawnedWork(lane) { - null === spawnedWorkDuringRender - ? (spawnedWorkDuringRender = [lane]) - : spawnedWorkDuringRender.push(lane); -} -function scheduleInteractions(root, lane, interactions) { - if (0 < interactions.size) { - var pendingInteractionMap = root.pendingInteractionMap, - pendingInteractions = pendingInteractionMap.get(lane); - null != pendingInteractions - ? interactions.forEach(function(interaction) { - pendingInteractions.has(interaction) || interaction.__count++; - pendingInteractions.add(interaction); - }) - : (pendingInteractionMap.set(lane, new Set(interactions)), - interactions.forEach(function(interaction) { - interaction.__count++; - })); - pendingInteractionMap = tracing.__subscriberRef.current; - if (null !== pendingInteractionMap) - pendingInteractionMap.onWorkScheduled( - interactions, - 1e3 * lane + root.interactionThreadID - ); - } -} -function schedulePendingInteractions(root, lane) { - scheduleInteractions(root, lane, tracing.__interactionsRef.current); -} -function startWorkOnPendingInteractions(root, lanes) { - var interactions = new Set(); - root.pendingInteractionMap.forEach(function( - scheduledInteractions, - scheduledLane - ) { - 0 !== (lanes & scheduledLane) && - scheduledInteractions.forEach(function(interaction) { - return interactions.add(interaction); - }); - }); - root.memoizedInteractions = interactions; - if (0 < interactions.size) { - var subscriber = tracing.__subscriberRef.current; - if (null !== subscriber) { - root = 1e3 * lanes + root.interactionThreadID; - try { - subscriber.onWorkStarted(interactions, root); - } catch (error) { - scheduleCallback(99, function() { - throw error; - }); - } - } - } -} -function finishPendingInteractions(root, committedLanes) { - var remainingLanesAfterCommit = root.pendingLanes; - try { - var subscriber = tracing.__subscriberRef.current; - if (null !== subscriber && 0 < root.memoizedInteractions.size) - subscriber.onWorkStopped( - root.memoizedInteractions, - 1e3 * committedLanes + root.interactionThreadID - ); - } catch (error) { - scheduleCallback(99, function() { - throw error; - }); - } finally { - var pendingInteractionMap = root.pendingInteractionMap; - pendingInteractionMap.forEach(function(scheduledInteractions, lane) { - 0 === (remainingLanesAfterCommit & lane) && - (pendingInteractionMap.delete(lane), - scheduledInteractions.forEach(function(interaction) { - interaction.__count--; - if (null !== subscriber && 0 === interaction.__count) - try { - subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$103) { - scheduleCallback(99, function() { - throw error$103; - }); - } - })); - }); - } -} function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; @@ -7773,8 +7816,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; this.actualDuration = 0; @@ -7815,11 +7858,11 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null), + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); + workInProgress.flags = current.flags & 1835008; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7856,17 +7899,16 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 4; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + mode |= 24; break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 2)), (type.elementType = REACT_PROFILER_TYPE), - (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), (type.stateNode = { effectDuration: 0, passiveEffectDuration: 0 }), type @@ -7874,7 +7916,6 @@ function createFiberFromTypeAndProps( case REACT_SUSPENSE_TYPE: return ( (type = createFiber(13, pendingProps, key, mode)), - (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.lanes = lanes), type @@ -7971,9 +8012,6 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.expirationTimes = createLaneMap(-1); this.entangledLanes = this.finishedLanes = this.mutableReadLanes = this.expiredLanes = this.pingedLanes = this.suspendedLanes = this.pendingLanes = 0; this.entanglements = createLaneMap(0); - this.interactionThreadID = tracing.unstable_getThreadID(); - this.memoizedInteractions = new Set(); - this.pendingInteractionMap = new Map(); } function createPortal(children, containerInfo, implementation) { var key = @@ -8055,7 +8093,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -8090,14 +8129,14 @@ batchedUpdatesImpl = function(fn, a) { (executionContext = prevExecutionContext), 0 === executionContext && ((workInProgressRootRenderTargetTime = now() + 500), - flushSyncCallbackQueue()); + includesLegacySyncCallbacks && flushSyncCallbacks()); } }; var roots = new Map(), - devToolsConfig$jscomp$inline_930 = { + devToolsConfig$jscomp$inline_1010 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.3-experimental-2d8d133e1", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8112,11 +8151,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1148 = { - bundleType: devToolsConfig$jscomp$inline_930.bundleType, - version: devToolsConfig$jscomp$inline_930.version, - rendererPackageName: devToolsConfig$jscomp$inline_930.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_930.rendererConfig, +var internals$jscomp$inline_1271 = { + bundleType: devToolsConfig$jscomp$inline_1010.bundleType, + version: devToolsConfig$jscomp$inline_1010.version, + rendererPackageName: devToolsConfig$jscomp$inline_1010.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1010.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8131,25 +8170,26 @@ var internals$jscomp$inline_1148 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_930.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1010.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, - getCurrentFiber: null + getCurrentFiber: null, + reconcilerVersion: "17.0.3-experimental-2d8d133e1" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1149 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1272 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1149.isDisabled && - hook$jscomp$inline_1149.supportsFiber + !hook$jscomp$inline_1272.isDisabled && + hook$jscomp$inline_1272.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1149.inject( - internals$jscomp$inline_1148 + (rendererID = hook$jscomp$inline_1272.inject( + internals$jscomp$inline_1271 )), - (injectedHook = hook$jscomp$inline_1149); + (injectedHook = hook$jscomp$inline_1272); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -8199,7 +8239,7 @@ exports.render = function(element, containerTag, callback) { if (!root) { root = new FiberRootNode(containerTag, 0, !1); var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 8); + isDevToolsPresent && (JSCompiler_inline_result |= 2); JSCompiler_inline_result = createFiber( 3, null, @@ -8208,6 +8248,7 @@ exports.render = function(element, containerTag, callback) { ); root.current = JSCompiler_inline_result; JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } @@ -8223,6 +8264,18 @@ exports.render = function(element, containerTag, callback) { else element = null; return element; }; +exports.sendAccessibilityEvent = function(handle, eventType) { + null != handle._nativeTag && + (handle._internalInstanceHandle + ? nativeFabricUIManager.sendAccessibilityEvent( + handle._internalInstanceHandle.stateNode.node, + eventType + ) + : ReactNativePrivateInterface.legacySendAccessibilityEvent( + handle._nativeTag, + eventType + )); +}; exports.unmountComponentAtNode = unmountComponentAtNode; exports.unmountComponentAtNodeAndRemoveContainer = function(containerTag) { unmountComponentAtNode(containerTag); diff --git a/Libraries/Settings/RCTSettingsPlugins.mm b/Libraries/Settings/RCTSettingsPlugins.mm index 09438ed1fc31f3..7ce46c64c84a4d 100644 --- a/Libraries/Settings/RCTSettingsPlugins.mm +++ b/Libraries/Settings/RCTSettingsPlugins.mm @@ -17,12 +17,13 @@ #import Class RCTSettingsClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"SettingsManager", RCTSettingsManagerCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/Libraries/Settings/React-RCTSettings.podspec b/Libraries/Settings/React-RCTSettings.podspec index 27ad00687977b6..68a43df5dfa345 100644 --- a/Libraries/Settings/React-RCTSettings.podspec +++ b/Libraries/Settings/React-RCTSettings.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTSettings" diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index 1b334d3fda0a70..97ce10d0a2099d 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -34,6 +34,8 @@ const Text: React.AbstractComponent< ellipsizeMode, onLongPress, onPress, + onPressIn, + onPressOut, onResponderGrant, onResponderMove, onResponderRelease, @@ -64,9 +66,11 @@ const Text: React.AbstractComponent< onPress, onPressIn(event) { setHighlighted(!suppressHighlighting); + onPressIn?.(event); }, onPressOut(event) { setHighlighted(false); + onPressOut?.(event); }, onResponderTerminationRequest_DEPRECATED: onResponderTerminationRequest, onStartShouldSetResponder_DEPRECATED: onStartShouldSetResponder, @@ -78,6 +82,8 @@ const Text: React.AbstractComponent< pressRetentionOffset, onLongPress, onPress, + onPressIn, + onPressOut, onResponderTerminationRequest, onStartShouldSetResponder, suppressHighlighting, diff --git a/Libraries/Text/TextProps.js b/Libraries/Text/TextProps.js index 4df56febb2e03a..dbf29e0d85a145 100644 --- a/Libraries/Text/TextProps.js +++ b/Libraries/Text/TextProps.js @@ -20,6 +20,8 @@ import type {TextStyleProp} from '../StyleSheet/StyleSheet'; import type { AccessibilityRole, AccessibilityState, + AccessibilityActionInfo, + AccessibilityActionEvent, } from '../Components/View/ViewAccessibility'; export type PressRetentionOffset = $ReadOnly<{| @@ -39,6 +41,8 @@ export type TextProps = $ReadOnly<{| * See https://reactnative.dev/docs/text.html#accessible */ accessible?: ?boolean, + accessibilityActions?: ?$ReadOnlyArray, + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, accessibilityHint?: ?Stringish, accessibilityLabel?: ?Stringish, accessibilityRole?: ?AccessibilityRole, @@ -122,6 +126,8 @@ export type TextProps = $ReadOnly<{| * See https://reactnative.dev/docs/text.html#onpress */ onPress?: ?(event: PressEvent) => mixed, + onPressIn?: ?(event: PressEvent) => mixed, + onPressOut?: ?(event: PressEvent) => mixed, onResponderGrant?: ?(event: PressEvent) => void, onResponderMove?: ?(event: PressEvent) => void, onResponderRelease?: ?(event: PressEvent) => void, diff --git a/Libraries/TurboModule/RCTExport.js b/Libraries/TurboModule/RCTExport.js index bbf236ed452d3d..d68194adb36194 100644 --- a/Libraries/TurboModule/RCTExport.js +++ b/Libraries/TurboModule/RCTExport.js @@ -35,4 +35,4 @@ export interface DEPRECATED_RCTExport { export interface TurboModule extends DEPRECATED_RCTExport {} -export type {RootTag} from '../ReactNative/RootTag.js'; +export type {RootTag} from '../Types/RootTagTypes.js'; diff --git a/Libraries/TurboModule/TurboModuleRegistry.js b/Libraries/TurboModule/TurboModuleRegistry.js index c8069e1b1265bc..90e30dd081591a 100644 --- a/Libraries/TurboModule/TurboModuleRegistry.js +++ b/Libraries/TurboModule/TurboModuleRegistry.js @@ -26,15 +26,6 @@ function requireModule(name: string): ?T { if (turboModuleProxy != null) { const module: ?T = turboModuleProxy(name); - if (module == null) { - // Common fixes: Verify the TurboModule is registered in the native binary, and adopts the code generated type-safe Spec base class. - // Safe to ignore when caused by importing legacy modules that are unused. - console.info( - 'Unable to get TurboModule for ' + - name + - '. Safe to ignore if module works.', - ); - } return module; } diff --git a/Libraries/TypeSafety/RCTTypeSafety.podspec b/Libraries/TypeSafety/RCTTypeSafety.podspec index 9fc19afc8d7dce..4fa95bcd96d790 100644 --- a/Libraries/TypeSafety/RCTTypeSafety.podspec +++ b/Libraries/TypeSafety/RCTTypeSafety.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "RCTTypeSafety" diff --git a/Libraries/Lists/VirtualizedListInjection.js b/Libraries/Types/RootTagTypes.js similarity index 62% rename from Libraries/Lists/VirtualizedListInjection.js rename to Libraries/Types/RootTagTypes.js index e8e00799b1b515..4fde211e5f02b0 100644 --- a/Libraries/Lists/VirtualizedListInjection.js +++ b/Libraries/Types/RootTagTypes.js @@ -4,12 +4,8 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict * @format - * @flow */ -'use strict'; - -export default { - unstable_enableVirtualizedListRemeasureChildrenIfNeeded: (null: ?boolean), -}; +export type {RootTag} from '../ReactNative/RootTag'; diff --git a/Libraries/Utilities/HMRClient.js b/Libraries/Utilities/HMRClient.js index e50b41eaebf367..e24c7642179cc5 100644 --- a/Libraries/Utilities/HMRClient.js +++ b/Libraries/Utilities/HMRClient.js @@ -16,8 +16,8 @@ const prettyFormat = require('pretty-format'); import getDevServer from '../Core/Devtools/getDevServer'; import NativeRedBox from '../NativeModules/specs/NativeRedBox'; -import * as LogBoxData from '../LogBox/Data/LogBoxData'; -import type {ExtendedError} from '../Core/Devtools/parseErrorStack'; +import LogBox from '../LogBox/LogBox'; +import type {ExtendedError} from '../Core/ExtendedError'; const pendingEntryPoints = []; let hmrClient = null; @@ -206,7 +206,7 @@ Error: ${e.message}`; client.on('update', ({isInitialUpdate}) => { if (client.isEnabled() && !isInitialUpdate) { dismissRedbox(); - LogBoxData.clear(); + LogBox.clearAllLogs(); } }); diff --git a/Libraries/Utilities/PerformanceLoggerContext.js b/Libraries/Utilities/PerformanceLoggerContext.js index 6e58752ccec1fb..92b77788099013 100644 --- a/Libraries/Utilities/PerformanceLoggerContext.js +++ b/Libraries/Utilities/PerformanceLoggerContext.js @@ -4,11 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow strict-local + * @flow strict * @format */ import * as React from 'react'; +import {useContext} from 'react'; import GlobalPerformanceLogger from './GlobalPerformanceLogger'; import type {IPerformanceLogger} from './createPerformanceLogger'; @@ -24,4 +25,9 @@ const PerformanceLoggerContext: React.Context = React.create if (__DEV__) { PerformanceLoggerContext.displayName = 'PerformanceLoggerContext'; } -module.exports = PerformanceLoggerContext; + +export function usePerformanceLogger(): IPerformanceLogger { + return useContext(PerformanceLoggerContext); +} + +export default PerformanceLoggerContext; diff --git a/Libraries/Utilities/registerGeneratedViewConfig.js b/Libraries/Utilities/registerGeneratedViewConfig.js deleted file mode 100644 index 5e2944571a8338..00000000000000 --- a/Libraries/Utilities/registerGeneratedViewConfig.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - * @format - */ - -import {createViewConfig} from '../NativeComponent/ViewConfig'; -import {type PartialViewConfig} from '../Renderer/shims/ReactNativeTypes'; -import ReactNativeViewConfigRegistry from '../Renderer/shims/ReactNativeViewConfigRegistry'; -import getNativeComponentAttributes from '../ReactNative/getNativeComponentAttributes'; -import verifyComponentAttributeEquivalence from './verifyComponentAttributeEquivalence'; - -function registerGeneratedViewConfig( - componentName: string, - partialViewConfig: PartialViewConfig, -) { - const staticViewConfig = createViewConfig(partialViewConfig); - - ReactNativeViewConfigRegistry.register(componentName, () => { - if (!global.RN$Bridgeless) { - const nativeViewConfig = getNativeComponentAttributes(componentName); - - verifyComponentAttributeEquivalence(nativeViewConfig, staticViewConfig); - } - - return staticViewConfig; - }); -} - -module.exports = registerGeneratedViewConfig; diff --git a/Libraries/Vibration/RCTVibrationPlugins.mm b/Libraries/Vibration/RCTVibrationPlugins.mm index 61421c2ef21e1c..d98ae4aae82b57 100644 --- a/Libraries/Vibration/RCTVibrationPlugins.mm +++ b/Libraries/Vibration/RCTVibrationPlugins.mm @@ -17,12 +17,13 @@ #import Class RCTVibrationClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"Vibration", RCTVibrationCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/Libraries/Vibration/React-RCTVibration.podspec b/Libraries/Vibration/React-RCTVibration.podspec index 4f5c3f496062f9..c8dfa06bde26cf 100644 --- a/Libraries/Vibration/React-RCTVibration.podspec +++ b/Libraries/Vibration/React-RCTVibration.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTVibration" diff --git a/Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.js b/Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.js index 4adadb6e87f227..ce3e9e679693ec 100644 --- a/Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.js +++ b/Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.js @@ -20,33 +20,39 @@ describe('YellowBox', () => { }); it('calling ignoreWarnings proxies to LogBox.ignoreLogs', () => { jest.spyOn(LogBox, 'ignoreLogs'); - jest.spyOn(console, 'warn').mockImplementation(() => {}); + const consoleWarn = jest + .spyOn(console, 'warn') + .mockImplementation(() => {}); YellowBox.ignoreWarnings(['foo']); expect(LogBox.ignoreLogs).toBeCalledWith(['foo']); - expect(console.warn).toBeCalledWith( + expect(consoleWarn).toBeCalledWith( 'YellowBox has been replaced with LogBox. Please call LogBox.ignoreLogs() instead.', ); }); it('calling install proxies to LogBox.install', () => { jest.spyOn(LogBox, 'install'); - jest.spyOn(console, 'warn').mockImplementation(() => {}); + const consoleWarn = jest + .spyOn(console, 'warn') + .mockImplementation(() => {}); YellowBox.install(); expect(LogBox.install).toBeCalled(); - expect(console.warn).toBeCalledWith( + expect(consoleWarn).toBeCalledWith( 'YellowBox has been replaced with LogBox. Please call LogBox.install() instead.', ); }); it('calling uninstall proxies to LogBox.uninstall', () => { jest.spyOn(LogBox, 'uninstall'); - jest.spyOn(console, 'warn').mockImplementation(() => {}); + const consoleWarn = jest + .spyOn(console, 'warn') + .mockImplementation(() => {}); YellowBox.uninstall(); expect(LogBox.uninstall).toBeCalled(); - expect(console.warn).toBeCalledWith( + expect(consoleWarn).toBeCalledWith( 'YellowBox has been replaced with LogBox. Please call LogBox.uninstall() instead.', ); }); diff --git a/React-Core.podspec b/React-Core.podspec index 2975b75567c647..cfe6821232158c 100644 --- a/React-Core.podspec +++ b/React-Core.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' header_subspecs = { @@ -48,7 +48,7 @@ Pod::Spec.new do |s| s.header_dir = "React" s.framework = "JavaScriptCore" s.library = "stdc++" - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/RCT-Folly\"", "DEFINES_MODULE" => "YES" } + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-hermes\" \"${PODS_ROOT}/Headers/Public/hermes-engine\"", "DEFINES_MODULE" => "YES" } s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\""} s.default_subspec = "Default" diff --git a/React/Base/RCTAssert.h b/React/Base/RCTAssert.h index 912d9237f91647..e4c77907f6e645 100644 --- a/React/Base/RCTAssert.h +++ b/React/Base/RCTAssert.h @@ -20,17 +20,17 @@ RCT_EXTERN BOOL RCTIsMainQueue(void); * assert handler through `RCTSetAssertFunction`. */ #ifndef NS_BLOCK_ASSERTIONS -#define RCTAssert(condition, ...) \ - do { \ - if ((condition) == 0) { \ - _RCTAssertFormat(#condition, __FILE__, __LINE__, __func__, __VA_ARGS__); \ - if (RCT_NSASSERT) { \ - [[NSAssertionHandler currentHandler] handleFailureInFunction:(NSString * _Nonnull) @(__func__) \ - file:(NSString * _Nonnull) @(__FILE__) \ - lineNumber:__LINE__ \ - description:__VA_ARGS__]; \ - } \ - } \ +#define RCTAssert(condition, ...) \ + do { \ + if ((condition) == 0) { \ + _RCTAssertFormat(#condition, __FILE__, __LINE__, __func__, __VA_ARGS__); \ + if (RCT_NSASSERT) { \ + [[NSAssertionHandler currentHandler] handleFailureInFunction:(NSString *_Nonnull)@(__func__) \ + file:(NSString *_Nonnull)@(__FILE__) \ + lineNumber:__LINE__ \ + description:__VA_ARGS__]; \ + } \ + } \ } while (false) #else #define RCTAssert(condition, ...) \ diff --git a/React/Base/RCTAssert.m b/React/Base/RCTAssert.m index e45589966cd357..634d7920d0122e 100644 --- a/React/Base/RCTAssert.m +++ b/React/Base/RCTAssert.m @@ -243,7 +243,11 @@ RCTFatalExceptionHandler RCTGetFatalExceptionHandler(void) void RCTEnableNewArchitectureViolationReporting(BOOL enabled) { +#if RCT_NEW_ARCHITECTURE + // Cannot disable the reporting in this mode. +#else newArchitectureViolationReporting = enabled; +#endif } static NSString *getNewArchitectureViolationMessage(id context, NSString *extra) diff --git a/React/Base/RCTBridge+Private.h b/React/Base/RCTBridge+Private.h index 438493e92310e0..70a20f0b00f632 100644 --- a/React/Base/RCTBridge+Private.h +++ b/React/Base/RCTBridge+Private.h @@ -146,6 +146,4 @@ RCT_EXTERN void RCTRegisterModule(Class); - (instancetype)initWithParentBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER; -- (void)forceGarbageCollection; - @end diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 87c1a616bd13e1..c87454216db17d 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -160,9 +160,9 @@ RCT_EXTERN void RCTEnableTurboModuleEagerInit(BOOL enabled); RCT_EXTERN BOOL RCTTurboModuleSharedMutexInitEnabled(void); RCT_EXTERN void RCTEnableTurboModuleSharedMutexInit(BOOL enabled); -// Turn on TurboModule shared mutex initialization -RCT_EXTERN BOOL RCTTurboModuleBlockGuardEnabled(void); -RCT_EXTERN void RCTEnableTurboModuleBlockGuard(BOOL enabled); +// Turn on TurboModule block guard for promises. +RCT_EXTERN BOOL RCTTurboModulePromisesBlockGuardEnabled(void); +RCT_EXTERN void RCTEnableTurboModulePromisesBlockGuard(BOOL enabled); /** * Async batched bridge used to communicate with the JavaScript application. @@ -231,6 +231,13 @@ RCT_EXTERN void RCTEnableTurboModuleBlockGuard(BOOL enabled); */ - (void)setRCTTurboModuleRegistry:(id)turboModuleRegistry; +/** + * This hook is called by the TurboModule infra with every TurboModule that's created. + * It allows the bridge to attach properties to TurboModules that give TurboModules + * access to Bridge APIs. + */ +- (void)attachBridgeAPIsToTurboModule:(id)module; + /** * Convenience method for retrieving all modules conforming to a given protocol. * Modules will be synchronously instantiated if they haven't already been, diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index f036dfd3378f22..441e57b6a14cbc 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -138,15 +138,15 @@ void RCTEnableTurboModuleSharedMutexInit(BOOL enabled) turboModuleSharedMutexInitEnabled = enabled; } -static BOOL turboModuleBlockGuardEnabled = NO; -BOOL RCTTurboModuleBlockGuardEnabled(void) +static BOOL turboModulePromisesBlockGuardEnabled = NO; +BOOL RCTTurboModulePromisesBlockGuardEnabled(void) { - return turboModuleBlockGuardEnabled; + return turboModulePromisesBlockGuardEnabled; } -void RCTEnableTurboModuleBlockGuard(BOOL enabled) +void RCTEnableTurboModulePromisesBlockGuard(BOOL enabled) { - turboModuleBlockGuardEnabled = enabled; + turboModulePromisesBlockGuardEnabled = enabled; } @interface RCTBridge () @@ -230,6 +230,11 @@ - (void)setRCTTurboModuleRegistry:(id)turboModuleRegistr [self.batchedBridge setRCTTurboModuleRegistry:turboModuleRegistry]; } +- (void)attachBridgeAPIsToTurboModule:(id)module +{ + [self.batchedBridge attachBridgeAPIsToTurboModule:module]; +} + - (void)didReceiveReloadCommand { #if RCT_ENABLE_INSPECTOR diff --git a/React/Base/RCTBridgeModule.h b/React/Base/RCTBridgeModule.h index b8d3ea6ee71fc0..31aaeffd2dfee7 100644 --- a/React/Base/RCTBridgeModule.h +++ b/React/Base/RCTBridgeModule.h @@ -14,6 +14,8 @@ @protocol RCTBridgeMethod; @class RCTModuleRegistry; @class RCTViewRegistry; +@class RCTBundleManager; +@class RCTCallableJSModules; /** * The type of a block that is capable of sending a response to a bridged @@ -133,7 +135,28 @@ RCT_EXTERN_C_END * viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED;`. If using Swift, add * `@objc var viewRegistry_DEPRECATED: RCTViewRegistry!` to your module. */ -@property (nonatomic, weak, readonly) RCTViewRegistry *viewRegistry_DEPRECATED; +@property (nonatomic, weak, readwrite) RCTViewRegistry *viewRegistry_DEPRECATED; + +/** + * A reference to the RCTBundleManager. Useful for modules that need to read + * or write to the app's bundle URL. + * + * To implement this in your module, just add `@synthesize bundleManager = + * _bundleManager;`. If using Swift, add `@objc var bundleManager: + * RCTBundleManager!` to your module. + */ +@property (nonatomic, weak, readwrite) RCTBundleManager *bundleManager; + +/** + * A reference to an RCTCallableJSModules. Useful for modules that need to + * call into methods on JavaScript modules registered as callable with + * React Native. + * + * To implement this in your module, just add `@synthesize callableJSModules = + * _callableJSModules;`. If using Swift, add `@objc var callableJSModules: + * RCTCallableJSModules!` to your module. + */ +@property (nonatomic, weak, readwrite) RCTCallableJSModules *callableJSModules; /** * A reference to the RCTBridge. Useful for modules that require access @@ -406,6 +429,21 @@ RCT_EXTERN_C_END - (id)moduleForName:(const char *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad; @end +typedef void (^RCTBridgelessBundleURLSetter)(NSURL *bundleURL); +typedef NSURL * (^RCTBridgelessBundleURLGetter)(); + +/** + * A class that allows NativeModules/TurboModules to read/write the bundleURL, with or without the bridge. + */ +@interface RCTBundleManager : NSObject +- (void)setBridge:(RCTBridge *)bridge; +- (void)setBridgelessBundleURLGetter:(RCTBridgelessBundleURLGetter)getter + andSetter:(RCTBridgelessBundleURLSetter)setter + andDefaultGetter:(RCTBridgelessBundleURLGetter)defaultGetter; +- (void)resetBundleURL; +@property NSURL *bundleURL; +@end + typedef UIView * (^RCTBridgelessComponentViewProvider)(NSNumber *); /** @@ -417,3 +455,24 @@ typedef UIView * (^RCTBridgelessComponentViewProvider)(NSNumber *); - (UIView *)viewForReactTag:(NSNumber *)reactTag; @end + +typedef void (^RCTBridgelessJSModuleMethodInvoker)( + NSString *moduleName, + NSString *methodName, + NSArray *args, + dispatch_block_t onComplete); + +/** + * A class that allows NativeModules to call methods on JavaScript modules registered + * as callable with React Native. + */ +@interface RCTCallableJSModules : NSObject +- (void)setBridge:(RCTBridge *)bridge; +- (void)setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker)bridgelessJSModuleMethodInvoker; + +- (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName withArgs:(NSArray *)args; +- (void)invokeModule:(NSString *)moduleName + method:(NSString *)methodName + withArgs:(NSArray *)args + onComplete:(dispatch_block_t)onComplete; +@end diff --git a/React/Base/RCTBundleHolderModule.h b/React/Base/RCTBundleHolderModule.h deleted file mode 100644 index b06d5ee5ad6955..00000000000000 --- a/React/Base/RCTBundleHolderModule.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * This protocol should be adopted when a turbo module needs to access the currently loaded JS bundle URL. - * In bridge-less React Native, it is a replacement for bridge.bundleURL. - */ -@protocol RCTBundleHolderModule - -@property (nonatomic, strong, readwrite) NSURL *bundleURL; - -@end diff --git a/React/Base/RCTBundleManager.m b/React/Base/RCTBundleManager.m new file mode 100644 index 00000000000000..b6c1b13652a49c --- /dev/null +++ b/React/Base/RCTBundleManager.m @@ -0,0 +1,78 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTAssert.h" +#import "RCTBridge+Private.h" +#import "RCTBridge.h" +#import "RCTBridgeModule.h" + +@implementation RCTBundleManager { + __weak RCTBridge *_bridge; + RCTBridgelessBundleURLGetter _bridgelessBundleURLGetter; + RCTBridgelessBundleURLSetter _bridgelessBundleURLSetter; + RCTBridgelessBundleURLGetter _bridgelessBundleURLDefaultGetter; +} + +- (void)setBridge:(RCTBridge *)bridge +{ + _bridge = bridge; +} + +- (void)setBridgelessBundleURLGetter:(RCTBridgelessBundleURLGetter)getter + andSetter:(RCTBridgelessBundleURLSetter)setter + andDefaultGetter:(RCTBridgelessBundleURLGetter)defaultGetter +{ + _bridgelessBundleURLGetter = getter; + _bridgelessBundleURLSetter = setter; + _bridgelessBundleURLDefaultGetter = defaultGetter; +} + +- (void)setBundleURL:(NSURL *)bundleURL +{ + if (_bridge) { + _bridge.bundleURL = bundleURL; + return; + } + + RCTAssert( + _bridgelessBundleURLSetter != nil, + @"RCTBundleManager: In bridgeless mode, RCTBridgelessBundleURLSetter must not be nil."); + _bridgelessBundleURLSetter(bundleURL); +} + +- (NSURL *)bundleURL +{ + if (_bridge) { + return _bridge.bundleURL; + } + + RCTAssert( + _bridgelessBundleURLGetter != nil, + @"RCTBundleManager: In bridgeless mode, RCTBridgelessBundleURLGetter must not be nil."); + + return _bridgelessBundleURLGetter(); +} + +- (void)resetBundleURL +{ + RCTBridge *strongBridge = _bridge; + if (strongBridge) { + strongBridge.bundleURL = [strongBridge.delegate sourceURLForBridge:strongBridge]; + return; + } + + RCTAssert( + _bridgelessBundleURLDefaultGetter != nil, + @"RCTBundleManager: In bridgeless mode, default RCTBridgelessBundleURLGetter must not be nil."); + RCTAssert( + _bridgelessBundleURLSetter != nil, + @"RCTBundleManager: In bridgeless mode, RCTBridgelessBundleURLSetter must not be nil."); + + _bridgelessBundleURLSetter(_bridgelessBundleURLDefaultGetter()); +} + +@end diff --git a/React/Base/RCTBundleURLProvider.h b/React/Base/RCTBundleURLProvider.h index 6e1dea3a66a678..890f8c3819a163 100644 --- a/React/Base/RCTBundleURLProvider.h +++ b/React/Base/RCTBundleURLProvider.h @@ -7,16 +7,19 @@ #import -#if defined(__cplusplus) -extern "C" { -#endif - -extern NSString *const RCTBundleURLProviderUpdatedNotification; +#import "RCTDefines.h" -extern const NSUInteger kRCTBundleURLProviderDefaultPort; +RCT_EXTERN NSString *const RCTBundleURLProviderUpdatedNotification; +RCT_EXTERN const NSUInteger kRCTBundleURLProviderDefaultPort; -#if defined(__cplusplus) -} +#if RCT_DEV_MENU +/** + * Allow/disallow accessing the packager server for various runtime scenario. + * For instance, if a test run should never access the packager, disable it + * by calling this function before initializing React Native (RCTBridge etc). + * By default the access is enabled. + */ +RCT_EXTERN void RCTBundleURLProviderAllowPackagerServerAccess(BOOL allowed); #endif @interface RCTBundleURLProvider : NSObject diff --git a/React/Base/RCTBundleURLProvider.mm b/React/Base/RCTBundleURLProvider.mm index cda955fe9f0d1c..393ca5631026ff 100644 --- a/React/Base/RCTBundleURLProvider.mm +++ b/React/Base/RCTBundleURLProvider.mm @@ -9,11 +9,20 @@ #import "RCTConvert.h" #import "RCTDefines.h" +#import "RCTLog.h" NSString *const RCTBundleURLProviderUpdatedNotification = @"RCTBundleURLProviderUpdatedNotification"; const NSUInteger kRCTBundleURLProviderDefaultPort = RCT_METRO_PORT; +#if RCT_DEV_MENU +static BOOL kRCTAllowPackagerAccess = YES; +void RCTBundleURLProviderAllowPackagerServerAccess(BOOL allowed) +{ + kRCTAllowPackagerAccess = allowed; +} +#endif + static NSString *const kRCTJsLocationKey = @"RCT_jsLocation"; static NSString *const kRCTEnableDevKey = @"RCT_enableDev"; static NSString *const kRCTEnableMinificationKey = @"RCT_enableMinification"; @@ -127,6 +136,12 @@ - (NSString *)packagerServerHost - (NSString *)packagerServerHostPort { +#if RCT_DEV_MENU + if (!kRCTAllowPackagerAccess) { + RCTLogInfo(@"Packager server access is disabled in this environment"); + return nil; + } +#endif NSString *location = [self jsLocation]; #if RCT_DEV_MENU if ([location length] && ![RCTBundleURLProvider isPackagerRunning:location]) { diff --git a/React/Base/RCTCallableJSModules.m b/React/Base/RCTCallableJSModules.m new file mode 100644 index 00000000000000..316d4dc56e4ee1 --- /dev/null +++ b/React/Base/RCTCallableJSModules.m @@ -0,0 +1,47 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTBridge.h" +#import "RCTBridgeModule.h" + +@implementation RCTCallableJSModules { + RCTBridgelessJSModuleMethodInvoker _bridgelessJSModuleMethodInvoker; + __weak RCTBridge *_bridge; +} + +- (void)setBridge:(RCTBridge *)bridge +{ + _bridge = bridge; +} + +- (void)setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker)bridgelessJSModuleMethodInvoker +{ + _bridgelessJSModuleMethodInvoker = bridgelessJSModuleMethodInvoker; +} + +- (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName withArgs:(NSArray *)args +{ + [self invokeModule:moduleName method:methodName withArgs:args onComplete:NULL]; +} + +- (void)invokeModule:(NSString *)moduleName + method:(NSString *)methodName + withArgs:(NSArray *)args + onComplete:(dispatch_block_t)onComplete +{ + RCTBridge *bridge = _bridge; + if (bridge) { + [bridge enqueueJSCall:moduleName method:methodName args:args completion:onComplete]; + return; + } + + if (_bridgelessJSModuleMethodInvoker) { + _bridgelessJSModuleMethodInvoker(moduleName, methodName, args, onComplete); + } +} + +@end diff --git a/React/Base/RCTConstants.h b/React/Base/RCTConstants.h index c34cbc52df4b82..d2ced08a2b153d 100644 --- a/React/Base/RCTConstants.h +++ b/React/Base/RCTConstants.h @@ -18,10 +18,16 @@ RCT_EXTERN BOOL RCTExperimentGetOnDemandViewMounting(void); RCT_EXTERN void RCTExperimentSetOnDemandViewMounting(BOOL value); /* - * It's an experimental feature that improves performance of hit-testing. + * Allows sending scroll events to Paper. */ -RCT_EXTERN BOOL RCTExperimentGetOptimizedHitTesting(void); -RCT_EXTERN void RCTExperimentSetOptimizedHitTesting(BOOL value); +RCT_EXTERN BOOL RCTExperimentGetSendScrollEventToPaper(void); +RCT_EXTERN void RCTExperimentSetSendScrollEventToPaper(BOOL value); + +/* + * Enables a fix for data race between state and scroll event. + */ +RCT_EXTERN BOOL RCTExperimentGetScrollViewEventRaceFix(void); +RCT_EXTERN void RCTExperimentSetScrollViewEventRaceFix(BOOL value); /* * Preemptive View Allocation diff --git a/React/Base/RCTConstants.m b/React/Base/RCTConstants.m index e701ea81e7b592..7ae08e18c314a5 100644 --- a/React/Base/RCTConstants.m +++ b/React/Base/RCTConstants.m @@ -26,18 +26,33 @@ void RCTExperimentSetOnDemandViewMounting(BOOL value) } /* - * Optimized hit-testing + * Send scroll events to Paper. */ -static BOOL RCTExperimentOptimizedHitTesting = NO; +static BOOL RCTExperimentSendScrollEventToPaper = YES; -BOOL RCTExperimentGetOptimizedHitTesting() +BOOL RCTExperimentGetSendScrollEventToPaper() { - return RCTExperimentOptimizedHitTesting; + return RCTExperimentSendScrollEventToPaper; } -void RCTExperimentSetOptimizedHitTesting(BOOL value) +void RCTExperimentSetSendScrollEventToPaper(BOOL value) { - RCTExperimentOptimizedHitTesting = value; + RCTExperimentSendScrollEventToPaper = value; +} + +/* + * Enable fix for data race between state and scroll event. + */ +static BOOL RCTExperimentScrollViewEventRaceFix = NO; + +BOOL RCTExperimentGetScrollViewEventRaceFix() +{ + return RCTExperimentScrollViewEventRaceFix; +} + +void RCTExperimentSetScrollViewEventRaceFix(BOOL value) +{ + RCTExperimentScrollViewEventRaceFix = value; } /* diff --git a/React/Base/RCTEventDispatcherProtocol.h b/React/Base/RCTEventDispatcherProtocol.h index 0c7039277264eb..9e54ccbf187ed8 100644 --- a/React/Base/RCTEventDispatcherProtocol.h +++ b/React/Base/RCTEventDispatcherProtocol.h @@ -8,7 +8,6 @@ #import #import -#import /** * The threshold at which text inputs will start warning that the JS thread @@ -80,7 +79,7 @@ typedef NS_ENUM(NSInteger, RCTTextEventType) { * This class wraps the -[RCTBridge enqueueJSCall:args:] method, and * provides some convenience methods for generating event calls. */ -@protocol RCTEventDispatcherProtocol +@protocol RCTEventDispatcherProtocol /** * Deprecated, do not use. diff --git a/Libraries/Components/ScrollView/ScrollViewStickyHeaderInjection.js b/React/Base/RCTInitializing.h similarity index 51% rename from Libraries/Components/ScrollView/ScrollViewStickyHeaderInjection.js rename to React/Base/RCTInitializing.h index ab8684ffb6818a..56b14b1c063b6e 100644 --- a/Libraries/Components/ScrollView/ScrollViewStickyHeaderInjection.js +++ b/React/Base/RCTInitializing.h @@ -1,17 +1,14 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - * - * @format - * @flow */ -'use strict'; +#import + +@protocol RCTInitializing -import typeof ScrollViewStickyHeader from './ScrollViewStickyHeader'; +- (void)initialize; -export default { - unstable_SH: (null: ?ScrollViewStickyHeader), -}; +@end diff --git a/React/Base/RCTJSInvokerModule.h b/React/Base/RCTJSInvokerModule.h deleted file mode 100644 index 59e79ceabb563f..00000000000000 --- a/React/Base/RCTJSInvokerModule.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * This protocol should be adopted when a turbo module needs to directly call into JavaScript. - * In bridge-less React Native, it is a replacement for [_bridge enqueueJSCall:]. - */ -@protocol RCTJSInvokerModule - -@optional -@property (nonatomic, copy) void (^invokeJS)(NSString *module, NSString *method, NSArray *args); -@property (nonatomic, copy) void (^invokeJSWithModuleDotMethod)(NSString *moduleDotMethod, NSArray *args); - -@end diff --git a/React/Base/RCTModuleData.h b/React/Base/RCTModuleData.h index cefd6209313f09..71e1950aac3bce 100644 --- a/React/Base/RCTModuleData.h +++ b/React/Base/RCTModuleData.h @@ -15,6 +15,8 @@ @class RCTBridge; @class RCTModuleRegistry; @class RCTViewRegistry; +@class RCTBundleManager; +@class RCTCallableJSModules; typedef id (^RCTBridgeModuleProvider)(void); @@ -23,18 +25,24 @@ typedef id (^RCTBridgeModuleProvider)(void); - (instancetype)initWithModuleClass:(Class)moduleClass bridge:(RCTBridge *)bridge moduleRegistry:(RCTModuleRegistry *)moduleRegistry - viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED; + viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED + bundleManager:(RCTBundleManager *)bundleManager + callableJSModules:(RCTCallableJSModules *)callableJSModules; - (instancetype)initWithModuleClass:(Class)moduleClass moduleProvider:(RCTBridgeModuleProvider)moduleProvider bridge:(RCTBridge *)bridge moduleRegistry:(RCTModuleRegistry *)moduleRegistry - viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED NS_DESIGNATED_INITIALIZER; + viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED + bundleManager:(RCTBundleManager *)bundleManager + callableJSModules:(RCTCallableJSModules *)callableJSModules NS_DESIGNATED_INITIALIZER; - (instancetype)initWithModuleInstance:(id)instance bridge:(RCTBridge *)bridge moduleRegistry:(RCTModuleRegistry *)moduleRegistry - viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED NS_DESIGNATED_INITIALIZER; + viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED + bundleManager:(RCTBundleManager *)bundleManager + callableJSModules:(RCTCallableJSModules *)callableJSModules NS_DESIGNATED_INITIALIZER; /** * Calls `constantsToExport` on the module and stores the result. Note that diff --git a/React/Base/RCTModuleData.mm b/React/Base/RCTModuleData.mm index f8a5459e66bf00..1a3d8839c79ca6 100644 --- a/React/Base/RCTModuleData.mm +++ b/React/Base/RCTModuleData.mm @@ -15,6 +15,7 @@ #import "RCTBridge+Private.h" #import "RCTBridge.h" +#import "RCTInitializing.h" #import "RCTLog.h" #import "RCTModuleMethod.h" #import "RCTProfile.h" @@ -50,6 +51,9 @@ @implementation RCTModuleData { BOOL _setupComplete; RCTModuleRegistry *_moduleRegistry; RCTViewRegistry *_viewRegistry_DEPRECATED; + RCTBundleManager *_bundleManager; + RCTCallableJSModules *_callableJSModules; + BOOL _isInitialized; } @synthesize methods = _methods; @@ -103,6 +107,8 @@ - (instancetype)initWithModuleClass:(Class)moduleClass bridge:(RCTBridge *)bridge moduleRegistry:(RCTModuleRegistry *)moduleRegistry viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED + bundleManager:(RCTBundleManager *)bundleManager + callableJSModules:(RCTCallableJSModules *)callableJSModules { return [self initWithModuleClass:moduleClass moduleProvider:^id { @@ -110,7 +116,9 @@ - (instancetype)initWithModuleClass:(Class)moduleClass } bridge:bridge moduleRegistry:moduleRegistry - viewRegistry_DEPRECATED:viewRegistry_DEPRECATED]; + viewRegistry_DEPRECATED:viewRegistry_DEPRECATED + bundleManager:bundleManager + callableJSModules:callableJSModules]; } - (instancetype)initWithModuleClass:(Class)moduleClass @@ -118,6 +126,8 @@ - (instancetype)initWithModuleClass:(Class)moduleClass bridge:(RCTBridge *)bridge moduleRegistry:(RCTModuleRegistry *)moduleRegistry viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED + bundleManager:(RCTBundleManager *)bundleManager + callableJSModules:(RCTCallableJSModules *)callableJSModules { if (self = [super init]) { _bridge = bridge; @@ -125,6 +135,8 @@ - (instancetype)initWithModuleClass:(Class)moduleClass _moduleProvider = [moduleProvider copy]; _moduleRegistry = moduleRegistry; _viewRegistry_DEPRECATED = viewRegistry_DEPRECATED; + _bundleManager = bundleManager; + _callableJSModules = callableJSModules; [self setUp]; } return self; @@ -134,6 +146,8 @@ - (instancetype)initWithModuleInstance:(id)instance bridge:(RCTBridge *)bridge moduleRegistry:(RCTModuleRegistry *)moduleRegistry viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED + bundleManager:(RCTBundleManager *)bundleManager + callableJSModules:(RCTCallableJSModules *)callableJSModules { if (self = [super init]) { _bridge = bridge; @@ -141,6 +155,8 @@ - (instancetype)initWithModuleInstance:(id)instance _moduleClass = [instance class]; _moduleRegistry = moduleRegistry; _viewRegistry_DEPRECATED = viewRegistry_DEPRECATED; + _bundleManager = bundleManager; + _callableJSModules = callableJSModules; [self setUp]; } return self; @@ -203,9 +219,15 @@ - (void)setUpInstanceAndBridge:(int32_t)requestId [self setBridgeForInstance]; [self setModuleRegistryForInstance]; [self setViewRegistryForInstance]; + [self setBundleManagerForInstance]; + [self setCallableJSModulesForInstance]; } [self setUpMethodQueue]; + + if (shouldSetup) { + [self _initializeModule]; + } } RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); @@ -284,6 +306,49 @@ - (void)setViewRegistryForInstance } } +- (void)setBundleManagerForInstance +{ + if ([_instance respondsToSelector:@selector(bundleManager)] && _instance.bundleManager != _bundleManager) { + RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setBundleManagerForInstance]", nil); + @try { + [(id)_instance setValue:_bundleManager forKey:@"bundleManager"]; + } @catch (NSException *exception) { + RCTLogError( + @"%@ has no setter or ivar for its module registry, which is not " + "permitted. You must either @synthesize the bundleManager property, " + "or provide your own setter method.", + self.name); + } + RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); + } +} + +- (void)setCallableJSModulesForInstance +{ + if ([_instance respondsToSelector:@selector(callableJSModules)] && + _instance.callableJSModules != _callableJSModules) { + RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setCallableJSModulesForInstance]", nil); + @try { + [(id)_instance setValue:_callableJSModules forKey:@"callableJSModules"]; + } @catch (NSException *exception) { + RCTLogError( + @"%@ has no setter or ivar for its module registry, which is not " + "permitted. You must either @synthesize the callableJSModules property, " + "or provide your own setter method.", + self.name); + } + RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); + } +} + +- (void)_initializeModule +{ + if (!_isInitialized && [_instance respondsToSelector:@selector(initialize)]) { + _isInitialized = YES; + [(id)_instance initialize]; + } +} + - (void)finishSetupForInstance { if (!_setupComplete && _instance) { diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm b/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm index 6bc6632509cabb..dac29387c41f72 100644 --- a/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm @@ -74,7 +74,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge initialProperties:initialProperties]; [surface start]; if (self = [super initWithSurface:surface sizeMeasureMode:sizeMeasureMode]) { - self.backgroundColor = [UIColor whiteColor]; + // Nothing specific to do. } RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm b/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm index 4b6817ebf4b22b..06d6eabe9d28dc 100644 --- a/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm @@ -60,6 +60,9 @@ - (instancetype)initWithSurface:(id)surface _surface.delegate = self; _stage = surface.stage; [self _updateViews]; + + // For backward compatibility with RCTRootView, set a color here instead of transparent (OS default). + self.backgroundColor = [UIColor whiteColor]; } return self; diff --git a/React/CoreModules/CoreModulesPlugins.mm b/React/CoreModules/CoreModulesPlugins.mm index c2d1b268b4fa6a..42ba5e45c9ecf5 100644 --- a/React/CoreModules/CoreModulesPlugins.mm +++ b/React/CoreModules/CoreModulesPlugins.mm @@ -17,7 +17,8 @@ #import Class RCTCoreModulesClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { + // Intentionally leak to avoid crashing after static destructors are run. + static const auto sCoreModuleClassMap = new const std::unordered_map{ {"AccessibilityManager", RCTAccessibilityManagerCls}, {"Appearance", RCTAppearanceCls}, {"DeviceInfo", RCTDeviceInfoCls}, @@ -45,8 +46,8 @@ Class RCTCoreModulesClassProvider(const char *name) { {"EventDispatcher", RCTEventDispatcherCls}, }; - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { + auto p = sCoreModuleClassMap->find(name); + if (p != sCoreModuleClassMap->end()) { auto classFunc = p->second; return classFunc(); } diff --git a/React/CoreModules/RCTDevLoadingView.mm b/React/CoreModules/RCTDevLoadingView.mm index ee8caf8a1cfe86..662eaa48c69c83 100644 --- a/React/CoreModules/RCTDevLoadingView.mm +++ b/React/CoreModules/RCTDevLoadingView.mm @@ -34,7 +34,7 @@ @implementation RCTDevLoadingView { dispatch_block_t _initialMessageBlock; } -@synthesize bridge = _bridge; +@synthesize bundleManager = _bundleManager; RCT_EXPORT_MODULE() @@ -60,16 +60,7 @@ + (void)setEnabled:(BOOL)enabled + (BOOL)requiresMainQueueSetup { - return YES; -} - -- (void)setBridge:(RCTBridge *)bridge -{ - _bridge = bridge; - - if (bridge.loading) { - [self showWithURL:bridge.bundleURL]; - } + return NO; } - (void)clearInitialMessageDelay @@ -104,11 +95,12 @@ - (UIColor *)dimColor:(UIColor *)c - (NSString *)getTextForHost { - if (self->_bridge.bundleURL == nil || self->_bridge.bundleURL.fileURL) { + NSURL *bundleURL = _bundleManager.bundleURL; + if (bundleURL == nil || bundleURL.fileURL) { return @"React Native"; } - return [NSString stringWithFormat:@"%@:%@", self->_bridge.bundleURL.host, self->_bridge.bundleURL.port]; + return [NSString stringWithFormat:@"%@:%@", bundleURL.host, bundleURL.port]; } - (void)showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(UIColor *)backgroundColor diff --git a/React/CoreModules/RCTDevMenu.mm b/React/CoreModules/RCTDevMenu.mm index 3e0cf8d7883f38..7e8f65d1cf0119 100644 --- a/React/CoreModules/RCTDevMenu.mm +++ b/React/CoreModules/RCTDevMenu.mm @@ -12,7 +12,6 @@ #import #import #import -#import #import #import #import @@ -86,7 +85,7 @@ - (NSString *)title typedef void (^RCTDevMenuAlertActionHandler)(UIAlertAction *action); -@interface RCTDevMenu () +@interface RCTDevMenu () @end @@ -97,7 +96,8 @@ @implementation RCTDevMenu { @synthesize bridge = _bridge; @synthesize moduleRegistry = _moduleRegistry; -@synthesize invokeJS = _invokeJS; +@synthesize callableJSModules = _callableJSModules; +@synthesize bundleManager = _bundleManager; RCT_EXPORT_MODULE() @@ -210,8 +210,8 @@ - (void)addItem:(RCTDevMenuItem *)item - (void)setDefaultJSBundle { [[RCTBundleURLProvider sharedSettings] resetToDefaults]; - self->_bridge.bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForFallbackResource:nil - fallbackExtension:nil]; + self->_bundleManager.bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForFallbackResource:nil + fallbackExtension:nil]; RCTTriggerReloadCommandListeners(@"Dev menu - reset to default"); } @@ -220,9 +220,9 @@ - (void)setDefaultJSBundle NSMutableArray *items = [NSMutableArray new]; // Add built-in items - __weak RCTBridge *bridge = _bridge; __weak RCTDevSettings *devSettings = [_moduleRegistry moduleForName:"DevSettings"]; __weak RCTDevMenu *weakSelf = self; + __weak RCTBundleManager *bundleManager = _bundleManager; [items addObject:[RCTDevMenuItem buttonItemWithTitle:@"Reload" handler:^{ @@ -242,7 +242,7 @@ - (void)setDefaultJSBundle handler:^{ [RCTInspectorDevServerHelper openURL:@"flipper://null/Hermesdebuggerrn?device=React%20Native" - withBundleURL:bridge.bundleURL + withBundleURL:bundleManager.bundleURL withErrorMessage:@"Failed to open Flipper. Please check that Metro is runnning."]; }]]; @@ -253,7 +253,7 @@ - (void)setDefaultJSBundle handler:^{ [RCTInspectorDevServerHelper openURL:@"flipper://null/React?device=React%20Native" - withBundleURL:bridge.bundleURL + withBundleURL:bundleManager.bundleURL withErrorMessage:@"Failed to open Flipper. Please check that Metro is runnning."]; }]]; } else if (devSettings.isRemoteDebuggingAvailable) { @@ -359,16 +359,15 @@ - (void)setDefaultJSBundle } [RCTBundleURLProvider sharedSettings].jsLocation = [NSString stringWithFormat:@"%@:%d", ipTextField.text, portNumber.intValue]; - __strong RCTBridge *strongBridge = bridge; - if (strongBridge) { - NSURL *bundleURL = bundleRoot.length - ? [[RCTBundleURLProvider sharedSettings] - jsBundleURLForBundleRoot:bundleRoot - fallbackResource:nil] - : [strongBridge.delegate sourceURLForBridge:strongBridge]; - strongBridge.bundleURL = bundleURL; - RCTTriggerReloadCommandListeners(@"Dev menu - apply changes"); + if (bundleRoot.length == 0) { + [bundleManager resetBundleURL]; + } else { + bundleManager.bundleURL = [[RCTBundleURLProvider sharedSettings] + jsBundleURLForBundleRoot:bundleRoot + fallbackResource:nil]; } + + RCTTriggerReloadCommandListeners(@"Dev menu - apply changes"); }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"Reset to Default" style:UIAlertActionStyleDefault @@ -419,11 +418,7 @@ - (void)setDefaultJSBundle _presentedItems = items; [RCTPresentedViewController() presentViewController:_actionSheet animated:YES completion:nil]; - if (_bridge) { - [_bridge enqueueJSCall:@"RCTNativeAppEventEmitter" method:@"emit" args:@[ @"RCTDevMenuShown" ] completion:NULL]; - } else { - _invokeJS(@"RCTNativeAppEventEmitter", @"emit", @[ @"RCTDevMenuShown" ]); - } + [_callableJSModules invokeModule:@"RCTNativeAppEventEmitter" method:@"emit" withArgs:@[ @"RCTDevMenuShown" ]]; } - (RCTDevMenuAlertActionHandler)alertActionHandlerForDevItem:(RCTDevMenuItem *__nullable)item diff --git a/React/CoreModules/RCTDevSettings.h b/React/CoreModules/RCTDevSettings.h index 45bb74a5c585db..9661caf51bfb3a 100644 --- a/React/CoreModules/RCTDevSettings.h +++ b/React/CoreModules/RCTDevSettings.h @@ -8,6 +8,7 @@ #import #import #import +#import @protocol RCTPackagerClientMethod; @@ -40,7 +41,7 @@ @end -@interface RCTDevSettings : RCTEventEmitter +@interface RCTDevSettings : RCTEventEmitter - (instancetype)initWithDataSource:(id)dataSource; diff --git a/React/CoreModules/RCTDevSettings.mm b/React/CoreModules/RCTDevSettings.mm index cc8f740cce79d8..0014b137da093e 100644 --- a/React/CoreModules/RCTDevSettings.mm +++ b/React/CoreModules/RCTDevSettings.mm @@ -12,7 +12,6 @@ #import #import #import -#import #import #import #import @@ -114,12 +113,7 @@ - (void)_reloadWithDefaults:(NSDictionary *)defaultValues @end -@interface RCTDevSettings () < - RCTBridgeModule, - RCTInvalidating, - NativeDevSettingsSpec, - RCTBundleHolderModule, - RCTDevSettingsInspectable> { +@interface RCTDevSettings () { BOOL _isJSLoaded; #if ENABLE_PACKAGER_CONNECTION RCTHandlerToken _reloadToken; @@ -133,8 +127,8 @@ @interface RCTDevSettings () < @implementation RCTDevSettings -@synthesize bundleURL = _bundleURL; @synthesize isInspectable = _isInspectable; +@synthesize bundleManager = _bundleManager; RCT_EXPORT_MODULE() @@ -172,44 +166,38 @@ - (instancetype)initWithDataSource:(id)dataSource return self; } -#if RCT_ENABLE_INSPECTOR -// In bridgeless mode, `setBridge` is not called, so dev server connection -// must be kicked off here. -- (void)setBundleURL:(NSURL *)bundleURL -{ - _bundleURL = bundleURL; - [RCTInspectorDevServerHelper connectWithBundleURL:_bundleURL]; -} -#endif - -- (void)setBridge:(RCTBridge *)bridge +- (void)initialize { - [super setBridge:bridge]; - #if ENABLE_PACKAGER_CONNECTION - RCTBridge *__weak weakBridge = bridge; - _reloadToken = [[RCTPackagerConnection sharedPackagerConnection] - addNotificationHandler:^(id params) { - if (params != (id)kCFNull && [params[@"debug"] boolValue]) { - weakBridge.executorClass = objc_lookUpClass("RCTWebSocketExecutor"); + if (self.bridge) { + RCTBridge *__weak weakBridge = self.bridge; + _reloadToken = [[RCTPackagerConnection sharedPackagerConnection] + addNotificationHandler:^(id params) { + if (params != (id)kCFNull && [params[@"debug"] boolValue]) { + weakBridge.executorClass = objc_lookUpClass("RCTWebSocketExecutor"); + } + RCTTriggerReloadCommandListeners(@"Global hotkey"); } - RCTTriggerReloadCommandListeners(@"Global hotkey"); - } - queue:dispatch_get_main_queue() - forMethod:@"reload"]; + queue:dispatch_get_main_queue() + forMethod:@"reload"]; + } #endif #if RCT_ENABLE_INSPECTOR - // We need this dispatch to the main thread because the bridge is not yet - // finished with its initialisation. By the time it relinquishes control of - // the main thread, this operation can be performed. - dispatch_async(dispatch_get_main_queue(), ^{ - [bridge - dispatchBlock:^{ - [RCTInspectorDevServerHelper connectWithBundleURL:bridge.bundleURL]; - } - queue:RCTJSThread]; - }); + if (self.bridge) { + // We need this dispatch to the main thread because the bridge is not yet + // finished with its initialisation. By the time it relinquishes control of + // the main thread, this operation can be performed. + dispatch_async(dispatch_get_main_queue(), ^{ + [self.bridge + dispatchBlock:^{ + [RCTInspectorDevServerHelper connectWithBundleURL:self.bundleManager.bundleURL]; + } + queue:RCTJSThread]; + }); + } else { + [RCTInspectorDevServerHelper connectWithBundleURL:self.bundleManager.bundleURL]; + } #endif dispatch_async(dispatch_get_main_queue(), ^{ @@ -269,10 +257,8 @@ - (BOOL)isRemoteDebuggingAvailable - (BOOL)isHotLoadingAvailable { - if (self.bridge.bundleURL) { - return !self.bridge.bundleURL.fileURL; // Only works when running from server - } else if (self.bundleURL) { - return !self.bundleURL.fileURL; + if (self.bundleManager.bundleURL) { + return !self.bundleManager.bundleURL.fileURL; } return NO; } @@ -359,16 +345,12 @@ - (void)_profilingSettingDidChange #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" if (enabled) { - if (self.bridge) { - [self.bridge enqueueJSCall:@"HMRClient" method:@"enable" args:@[] completion:NULL]; - } else if (self.invokeJS) { - self.invokeJS(@"HMRClient", @"enable", @[]); + if (self.callableJSModules) { + [self.callableJSModules invokeModule:@"HMRClient" method:@"enable" withArgs:@[]]; } } else { - if (self.bridge) { - [self.bridge enqueueJSCall:@"HMRClient" method:@"disable" args:@[] completion:NULL]; - } else if (self.invokeJS) { - self.invokeJS(@"HMRClient", @"disable", @[]); + if (self.callableJSModules) { + [self.callableJSModules invokeModule:@"HMRClient" method:@"disable" withArgs:@[]]; } } #pragma clang diagnostic pop @@ -450,13 +432,10 @@ - (void)setupHMRClientWithBundleURL:(NSURL *)bundleURL NSString *const host = bundleURL.host; NSNumber *const port = bundleURL.port; BOOL isHotLoadingEnabled = self.isHotLoadingEnabled; - if (self.bridge) { - [self.bridge enqueueJSCall:@"HMRClient" - method:@"setup" - args:@[ @"ios", path, host, RCTNullIfNil(port), @(isHotLoadingEnabled) ] - completion:NULL]; - } else { - self.invokeJS(@"HMRClient", @"setup", @[ @"ios", path, host, RCTNullIfNil(port), @(isHotLoadingEnabled) ]); + if (self.callableJSModules) { + [self.callableJSModules invokeModule:@"HMRClient" + method:@"setup" + withArgs:@[ @"ios", path, host, RCTNullIfNil(port), @(isHotLoadingEnabled) ]]; } } } @@ -464,13 +443,10 @@ - (void)setupHMRClientWithBundleURL:(NSURL *)bundleURL - (void)setupHMRClientWithAdditionalBundleURL:(NSURL *)bundleURL { if (bundleURL && !bundleURL.fileURL) { // isHotLoadingAvailable check - if (self.bridge) { - [self.bridge enqueueJSCall:@"HMRClient" - method:@"registerBundle" - args:@[ [bundleURL absoluteString] ] - completion:NULL]; - } else { - self.invokeJS(@"HMRClient", @"registerBundle", @[ [bundleURL absoluteString] ]); + if (self.callableJSModules) { + [self.callableJSModules invokeModule:@"HMRClient" + method:@"registerBundle" + withArgs:@[ [bundleURL absoluteString] ]]; } } } @@ -531,6 +507,9 @@ - (instancetype)initWithDataSource:(id)dataSource { return [super init]; } +- (void)initialize +{ +} - (BOOL)isHotLoadingAvailable { return NO; diff --git a/React/CoreModules/RCTDevSplitBundleLoader.mm b/React/CoreModules/RCTDevSplitBundleLoader.mm index 4a2243e17c2725..4afc2ee4fd7415 100644 --- a/React/CoreModules/RCTDevSplitBundleLoader.mm +++ b/React/CoreModules/RCTDevSplitBundleLoader.mm @@ -28,7 +28,7 @@ @implementation RCTDevSplitBundleLoader @synthesize bridge = _bridge; @synthesize loadScript = _loadScript; -@synthesize turboModuleRegistry = _turboModuleRegistry; +@synthesize moduleRegistry = _moduleRegistry; RCT_EXPORT_MODULE() @@ -37,11 +37,6 @@ + (BOOL)requiresMainQueueSetup return NO; } -- (void)setBridge:(RCTBridge *)bridge -{ - _bridge = bridge; -} - RCT_EXPORT_METHOD(loadBundle : (NSString *)bundlePath resolve : (RCTPromiseResolveBlock)resolve reject @@ -69,7 +64,7 @@ - (void)setBridge:(RCTBridge *)bridge } __typeof(self) strongSelf = weakSelf; strongSelf->_loadScript(source); - RCTDevSettings *devSettings = [strongSelf->_turboModuleRegistry moduleForName:"RCTDevSettings"]; + RCTDevSettings *devSettings = [strongSelf->_moduleRegistry moduleForName:"RCTDevSettings"]; [devSettings setupHMRClientWithAdditionalBundleURL:source.url]; resolve(@YES); }]; diff --git a/React/CoreModules/RCTDeviceInfo.mm b/React/CoreModules/RCTDeviceInfo.mm index f470f99572e8cf..b4ab579c737cd1 100644 --- a/React/CoreModules/RCTDeviceInfo.mm +++ b/React/CoreModules/RCTDeviceInfo.mm @@ -28,7 +28,6 @@ @implementation RCTDeviceInfo { } @synthesize moduleRegistry = _moduleRegistry; -@synthesize turboModuleRegistry = _turboModuleRegistry; RCT_EXPORT_MODULE() diff --git a/React/CoreModules/RCTEventDispatcher.h b/React/CoreModules/RCTEventDispatcher.h index e15c20723252dd..bbcd643cdfb089 100644 --- a/React/CoreModules/RCTEventDispatcher.h +++ b/React/CoreModules/RCTEventDispatcher.h @@ -9,9 +9,10 @@ #import #import +#import /** * This class wraps the -[RCTBridge enqueueJSCall:args:] method, and * provides some convenience methods for generating event calls. */ -@interface RCTEventDispatcher : NSObject +@interface RCTEventDispatcher : NSObject @end diff --git a/React/CoreModules/RCTEventDispatcher.mm b/React/CoreModules/RCTEventDispatcher.mm index 1edb079a9bfcd7..d9c690538967b0 100644 --- a/React/CoreModules/RCTEventDispatcher.mm +++ b/React/CoreModules/RCTEventDispatcher.mm @@ -42,14 +42,12 @@ @implementation RCTEventDispatcher { @synthesize bridge = _bridge; @synthesize dispatchToJSThread = _dispatchToJSThread; -@synthesize invokeJS = _invokeJS; -@synthesize invokeJSWithModuleDotMethod = _invokeJSWithModuleDotMethod; +@synthesize callableJSModules = _callableJSModules; RCT_EXPORT_MODULE() -- (void)setBridge:(RCTBridge *)bridge +- (void)initialize { - _bridge = bridge; _events = [NSMutableDictionary new]; _eventQueue = [NSMutableArray new]; _eventQueueLock = [NSLock new]; @@ -60,26 +58,14 @@ - (void)setBridge:(RCTBridge *)bridge - (void)sendAppEventWithName:(NSString *)name body:(id)body { - if (_bridge) { - [_bridge enqueueJSCall:@"RCTNativeAppEventEmitter" - method:@"emit" - args:body ? @[ name, body ] : @[ name ] - completion:NULL]; - } else if (_invokeJS) { - _invokeJS(@"RCTNativeAppEventEmitter", @"emit", body ? @[ name, body ] : @[ name ]); - } + [_callableJSModules invokeModule:@"RCTNativeAppEventEmitter" + method:@"emit" + withArgs:body ? @[ name, body ] : @[ name ]]; } - (void)sendDeviceEventWithName:(NSString *)name body:(id)body { - if (_bridge) { - [_bridge enqueueJSCall:@"RCTDeviceEventEmitter" - method:@"emit" - args:body ? @[ name, body ] : @[ name ] - completion:NULL]; - } else if (_invokeJS) { - _invokeJS(@"RCTDeviceEventEmitter", @"emit", body ? @[ name, body ] : @[ name ]); - } + [_callableJSModules invokeModule:@"RCTDeviceEventEmitter" method:@"emit" withArgs:body ? @[ name, body ] : @[ name ]]; } - (void)sendTextEventWithType:(RCTTextEventType)type @@ -196,11 +182,12 @@ - (void)removeDispatchObserver:(id)observer - (void)dispatchEvent:(id)event { - if (_bridge) { - [_bridge enqueueJSCall:[[event class] moduleDotMethod] args:[event arguments]]; - } else if (_invokeJSWithModuleDotMethod) { - _invokeJSWithModuleDotMethod([[event class] moduleDotMethod], [event arguments]); - } + NSString *moduleDotMethod = [[event class] moduleDotMethod]; + NSArray *const components = [moduleDotMethod componentsSeparatedByString:@"."]; + NSString *const moduleName = components[0]; + NSString *const methodName = components[1]; + + [_callableJSModules invokeModule:moduleName method:methodName withArgs:[event arguments]]; } - (dispatch_queue_t)methodQueue diff --git a/React/CoreModules/RCTKeyboardObserver.mm b/React/CoreModules/RCTKeyboardObserver.mm index 072df8ce3d7efe..1901a08e1242b4 100644 --- a/React/CoreModules/RCTKeyboardObserver.mm +++ b/React/CoreModules/RCTKeyboardObserver.mm @@ -60,7 +60,7 @@ - (void)stopObserving #define IMPLEMENT_KEYBOARD_HANDLER(EVENT) \ -(void)EVENT : (NSNotification *)notification \ { \ - if (!self.bridge && !self.invokeJS) { \ + if (!self.callableJSModules) { \ return; \ } \ [self sendEventWithName:@ #EVENT body:RCTParseKeyboardNotification(notification)]; \ diff --git a/React/CoreModules/RCTRedBox.mm b/React/CoreModules/RCTRedBox.mm index ce47519514d862..943a7e36e65b66 100644 --- a/React/CoreModules/RCTRedBox.mm +++ b/React/CoreModules/RCTRedBox.mm @@ -210,12 +210,6 @@ - (NSInteger)bottomSafeViewHeight RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) -- (void)dealloc -{ - _stackTraceTableView.dataSource = nil; - _stackTraceTableView.delegate = nil; -} - - (NSString *)stripAnsi:(NSString *)text { NSError *error = nil; @@ -456,6 +450,7 @@ @implementation RCTRedBox { @synthesize bridge = _bridge; @synthesize moduleRegistry = _moduleRegistry; +@synthesize bundleManager = _bundleManager; RCT_EXPORT_MODULE() @@ -642,7 +637,7 @@ - (void)invalidate - (void)redBoxWindow:(__unused RCTRedBoxWindow *)redBoxWindow openStackFrameInEditor:(RCTJSStackFrame *)stackFrame { - NSURL *const bundleURL = _overrideBundleURL ?: _bridge.bundleURL; + NSURL *const bundleURL = _overrideBundleURL ?: _bundleManager.bundleURL; if (![bundleURL.scheme hasPrefix:@"http"]) { RCTLogWarn(@"Cannot open stack frame in editor because you're not connected to the packager."); return; diff --git a/React/CoreModules/RCTSourceCode.mm b/React/CoreModules/RCTSourceCode.mm index 92cb27ef4e6929..1b3e424f831d91 100644 --- a/React/CoreModules/RCTSourceCode.mm +++ b/React/CoreModules/RCTSourceCode.mm @@ -23,6 +23,7 @@ @implementation RCTSourceCode RCT_EXPORT_MODULE() @synthesize bridge = _bridge; +@synthesize bundleManager = _bundleManager; + (BOOL)requiresMainQueueSetup { @@ -37,7 +38,7 @@ + (BOOL)requiresMainQueueSetup - (NSDictionary *)getConstants { return @{ - @"scriptURL" : self.bridge.bundleURL.absoluteString ?: @"", + @"scriptURL" : self.bundleManager.bundleURL.absoluteString ?: @"", }; } diff --git a/React/CoreModules/RCTTiming.h b/React/CoreModules/RCTTiming.h index 4776f85e2b7673..7c197aaa9c9db0 100644 --- a/React/CoreModules/RCTTiming.h +++ b/React/CoreModules/RCTTiming.h @@ -9,6 +9,7 @@ #import #import +#import #import @protocol RCTTimingDelegate @@ -19,7 +20,7 @@ @end -@interface RCTTiming : NSObject +@interface RCTTiming : NSObject - (instancetype)initWithDelegate:(id)delegate; - (void)createTimerForNextFrame:(nonnull NSNumber *)callbackID diff --git a/React/CoreModules/RCTTiming.mm b/React/CoreModules/RCTTiming.mm index 7517771008649f..70f0543eca7b39 100644 --- a/React/CoreModules/RCTTiming.mm +++ b/React/CoreModules/RCTTiming.mm @@ -118,11 +118,9 @@ - (instancetype)initWithDelegate:(id)delegate return self; } -- (void)setBridge:(RCTBridge *)bridge +- (void)initialize { - RCTAssert(!_bridge, @"Should never be initialized twice!"); [self setup]; - _bridge = bridge; } - (void)setup diff --git a/React/CoreModules/React-CoreModules.podspec b/React/CoreModules/React-CoreModules.podspec index 510a57648da060..751b4719dca49b 100644 --- a/React/CoreModules/React-CoreModules.podspec +++ b/React/CoreModules/React-CoreModules.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-CoreModules" diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index be1798f19395e6..0f1a601f4a6ec0 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -40,7 +40,7 @@ #import #ifndef RCT_USE_HERMES -#if __has_include() +#if __has_include() #define RCT_USE_HERMES 1 #else #define RCT_USE_HERMES 0 @@ -48,7 +48,7 @@ #endif #if RCT_USE_HERMES -#import +#import #else #import "JSCExecutorFactory.h" #endif @@ -194,7 +194,6 @@ @interface RCTCxxBridge () - (instancetype)initWithParentBridge:(RCTBridge *)bridge; - (void)partialBatchDidFlush; - (void)batchDidComplete; -- (void)forceGarbageCollection; @end @@ -236,6 +235,8 @@ @implementation RCTCxxBridge { RCTModuleRegistry *_objCModuleRegistry; RCTViewRegistry *_viewRegistry_DEPRECATED; + RCTBundleManager *_bundleManager; + RCTCallableJSModules *_callableJSModules; } @synthesize bridgeDescription = _bridgeDescription; @@ -249,6 +250,44 @@ - (void)setRCTTurboModuleRegistry:(id)turboModuleRegistr [_objCModuleRegistry setTurboModuleRegistry:_turboModuleRegistry]; } +- (void)attachBridgeAPIsToTurboModule:(id)module +{ + id bridgeModule = (id)module; + /** + * Attach the RCTViewRegistry to this TurboModule, which allows this TurboModule + * To query a React component's UIView, given its reactTag. + * + * Usage: In the TurboModule @implementation, include: + * `@synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED` + */ + if ([bridgeModule respondsToSelector:@selector(setViewRegistry_DEPRECATED:)]) { + bridgeModule.viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED; + } + + /** + * Attach the RCTBundleManager to this TurboModule, which allows this TurboModule to + * read from/write to the app's bundle URL. + * + * Usage: In the TurboModule @implementation, include: + * `@synthesize bundleManager = _bundleManager` + */ + if ([bridgeModule respondsToSelector:@selector(setBundleManager:)]) { + bridgeModule.bundleManager = _bundleManager; + } + + /** + * Attach the RCTCallableJSModules to this TurboModule, which allows this TurboModule + * to call JS Module methods. + * + * Usage: In the TurboModule @implementation, include: + * `@synthesize callableJSModules = _callableJSModules` + */ + + if ([bridgeModule respondsToSelector:@selector(setCallableJSModules:)]) { + bridgeModule.callableJSModules = _callableJSModules; + } +} + - (std::shared_ptr)jsMessageThread { return _jsMessageThread; @@ -285,8 +324,12 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge _moduleDataByID = [NSMutableArray new]; _objCModuleRegistry = [RCTModuleRegistry new]; [_objCModuleRegistry setBridge:self]; + _bundleManager = [RCTBundleManager new]; + [_bundleManager setBridge:self]; _viewRegistry_DEPRECATED = [RCTViewRegistry new]; [_viewRegistry_DEPRECATED setBridge:self]; + _callableJSModules = [RCTCallableJSModules new]; + [_callableJSModules setBridge:self]; [RCTBridge setCurrentBridge:self]; @@ -337,11 +380,6 @@ - (void)_tryAndHandleError:(dispatch_block_t)block } - (void)handleMemoryWarning -{ - [self forceGarbageCollection]; -} - -- (void)forceGarbageCollection { // We only want to run garbage collector when the loading is finished // and the instance is valid. @@ -466,6 +504,14 @@ - (void)start // Load the source asynchronously, then store it for later execution. dispatch_group_enter(prepareBridge); __block NSData *sourceCode; + +#if (RCT_DEV | RCT_ENABLE_LOADING_VIEW) && __has_include() + { + id loadingView = [self moduleForName:@"DevLoadingView" lazilyLoadIfNecessary:YES]; + [loadingView showWithURL:self.bundleURL]; + } +#endif + [self loadSource:^(NSError *error, RCTSource *source) { if (error) { @@ -763,7 +809,9 @@ - (void)updateModuleWithInstance:(id)instance moduleData = [[RCTModuleData alloc] initWithModuleClass:moduleClass bridge:self moduleRegistry:_objCModuleRegistry - viewRegistry_DEPRECATED:_viewRegistry_DEPRECATED]; + viewRegistry_DEPRECATED:_viewRegistry_DEPRECATED + bundleManager:_bundleManager + callableJSModules:_callableJSModules]; BridgeNativeModulePerfLogger::moduleDataCreateEnd([moduleName UTF8String], moduleDataId); _moduleDataByName[moduleName] = moduleData; @@ -838,7 +886,9 @@ - (void)registerExtraModules RCTModuleData *moduleData = [[RCTModuleData alloc] initWithModuleInstance:module bridge:self moduleRegistry:_objCModuleRegistry - viewRegistry_DEPRECATED:_viewRegistry_DEPRECATED]; + viewRegistry_DEPRECATED:_viewRegistry_DEPRECATED + bundleManager:_bundleManager + callableJSModules:_callableJSModules]; BridgeNativeModulePerfLogger::moduleDataCreateEnd([moduleName UTF8String], moduleDataId); _moduleDataByName[moduleName] = moduleData; @@ -892,7 +942,9 @@ - (void)registerExtraLazyModules moduleData = [[RCTModuleData alloc] initWithModuleClass:moduleClass bridge:self moduleRegistry:_objCModuleRegistry - viewRegistry_DEPRECATED:_viewRegistry_DEPRECATED]; + viewRegistry_DEPRECATED:_viewRegistry_DEPRECATED + bundleManager:_bundleManager + callableJSModules:_callableJSModules]; BridgeNativeModulePerfLogger::moduleDataCreateEnd([moduleName UTF8String], moduleDataId); _moduleDataByName[moduleName] = moduleData; diff --git a/React/CxxModule/RCTNativeModule.mm b/React/CxxModule/RCTNativeModule.mm index be74794fc572c0..cea144f5f469da 100644 --- a/React/CxxModule/RCTNativeModule.mm +++ b/React/CxxModule/RCTNativeModule.mm @@ -100,7 +100,9 @@ static MethodCallResult invokeInner( #else (void)(callId); #endif - invokeInner(weakBridge, weakModuleData, methodId, std::move(params), callId, isSyncModule ? Sync : Async); + @autoreleasepool { + invokeInner(weakBridge, weakModuleData, methodId, std::move(params), callId, isSyncModule ? Sync : Async); + } }; if (isSyncModule) { diff --git a/React/FBReactNativeSpec/FBReactNativeSpec.podspec b/React/FBReactNativeSpec/FBReactNativeSpec.podspec index 8238056b480623..6d35023920bb2d 100644 --- a/React/FBReactNativeSpec/FBReactNativeSpec.podspec +++ b/React/FBReactNativeSpec/FBReactNativeSpec.podspec @@ -18,7 +18,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "FBReactNativeSpec" diff --git a/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm b/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm index 82562fa1be629f..3e216fb625b881 100644 --- a/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm @@ -7,6 +7,7 @@ #import "RCTLegacyViewManagerInteropComponentView.h" +#import #import #import #import @@ -28,6 +29,8 @@ @implementation RCTLegacyViewManagerInteropComponentView { - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { + RCTWarnNotAllowedForNewArchitecture( + self, @"ViewManager with interop layer is not allowed in the new architecture."); static const auto defaultProps = std::make_shared(); _props = defaultProps; _viewsToBeMounted = [NSMutableArray new]; diff --git a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h index 823ac45486e206..3a93dbc70cc5c0 100644 --- a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h +++ b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h @@ -25,11 +25,8 @@ * Subclasses may override this method. * Default implementation calls `[UIViewController dismissViewControllerAnimated:completion:]`. */ -- (void)dismissViewController:(UIViewController *)modalViewController animated:(BOOL)animated; - -/** - * Should be called by subclasses when ViewController is dismissed. - */ -- (void)didDismissViewController; +- (void)dismissViewController:(UIViewController *)modalViewController + animated:(BOOL)animated + completion:(void (^)(void))completion; @end diff --git a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm index 94abe2b99c51a2..5072d47f6b95ed 100644 --- a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm @@ -102,6 +102,7 @@ @implementation RCTModalHostViewComponentView { RCTFabricModalHostViewController *_viewController; ModalHostViewShadowNode::ConcreteState::Shared _state; BOOL _shouldAnimatePresentation; + BOOL _shouldPresent; BOOL _isPresented; UIView *_modalContentsSnapshot; } @@ -137,47 +138,60 @@ - (void)presentViewController:(UIViewController *)modalViewController [controller presentViewController:modalViewController animated:animated completion:completion]; } -- (void)dismissViewController:(UIViewController *)modalViewController animated:(BOOL)animated -{ - [modalViewController dismissViewControllerAnimated:animated - completion:^{ - [self didDismissViewController]; - }]; -} - -- (void)didDismissViewController +- (void)dismissViewController:(UIViewController *)modalViewController + animated:(BOOL)animated + completion:(void (^)(void))completion { - const auto &props = *std::static_pointer_cast(_props); - [[RCTBridge currentBridge].modalManager modalDismissed:@(props.identifier)]; + [modalViewController dismissViewControllerAnimated:animated completion:completion]; } - (void)ensurePresentedOnlyIfNeeded { - BOOL shouldBePresented = !_isPresented && self.window; + BOOL shouldBePresented = !_isPresented && _shouldPresent && self.window; if (shouldBePresented) { _isPresented = YES; [self presentViewController:self.viewController animated:_shouldAnimatePresentation completion:^{ - if (!self->_eventEmitter) { - return; - } + auto eventEmitter = [self modalEventEmitter]; + if (eventEmitter) { + eventEmitter->onShow(ModalHostViewEventEmitter::OnShow{}); - assert(std::dynamic_pointer_cast(self->_eventEmitter)); - auto eventEmitter = - std::static_pointer_cast(self->_eventEmitter); - eventEmitter->onShow(ModalHostViewEventEmitter::OnShow{}); + // A hack so that EventEmitter.cpp's eventTarget_ does not become null when modal is dismissed + eventEmitter->setEnabled(true); + } }]; } - BOOL shouldBeHidden = _isPresented && !self.superview; + BOOL shouldBeHidden = _isPresented && (!_shouldPresent || !self.superview); if (shouldBeHidden) { _isPresented = NO; // To animate dismissal of view controller, snapshot of // view hierarchy needs to be added to the UIViewController. - [self.viewController.view addSubview:_modalContentsSnapshot]; - [self dismissViewController:self.viewController animated:_shouldAnimatePresentation]; + UIView *snapshot = _modalContentsSnapshot; + [self.viewController.view addSubview:snapshot]; + + auto eventEmitter = [self modalEventEmitter]; + [self dismissViewController:self.viewController + animated:_shouldAnimatePresentation + completion:^{ + [snapshot removeFromSuperview]; + + if (eventEmitter) { + eventEmitter->onDismiss(ModalHostViewEventEmitter::OnDismiss{}); + } + }]; + } +} + +- (std::shared_ptr)modalEventEmitter +{ + if (!self->_eventEmitter) { + return nullptr; } + + assert(std::dynamic_pointer_cast(self->_eventEmitter)); + return std::static_pointer_cast(self->_eventEmitter); } #pragma mark - RCTMountingTransactionObserving @@ -205,10 +219,8 @@ - (void)didMoveToSuperview - (void)boundsDidChange:(CGRect)newBounds { - if (_eventEmitter) { - assert(std::dynamic_pointer_cast(_eventEmitter)); - - auto eventEmitter = std::static_pointer_cast(_eventEmitter); + auto eventEmitter = [self modalEventEmitter]; + if (eventEmitter) { eventEmitter->onOrientationChange(onOrientationChangeStruct(newBounds)); } @@ -231,6 +243,7 @@ - (void)prepareForRecycle _state.reset(); _viewController = nil; _isPresented = NO; + _shouldPresent = NO; } - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps @@ -247,6 +260,9 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & self.viewController.modalPresentationStyle = presentationConfiguration(newProps); + _shouldPresent = newProps.visible; + [self ensurePresentedOnlyIfNeeded]; + [super updateProps:props oldProps:oldProps]; } diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 48816f4c3cf3b3..535a8c6c1c47dc 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -87,6 +87,8 @@ @implementation RCTScrollViewComponentView { BOOL _isUserTriggeredScrolling; BOOL _isOnDemandViewMountingEnabled; + BOOL _sendScrollEventToPaper; + BOOL _enableScrollViewEventRaceFix; CGPoint _contentOffsetWhenClipped; NSMutableArray *> *_childComponentViews; } @@ -106,6 +108,8 @@ - (instancetype)initWithFrame:(CGRect)frame _props = defaultProps; _isOnDemandViewMountingEnabled = RCTExperimentGetOnDemandViewMounting(); + _sendScrollEventToPaper = RCTExperimentGetSendScrollEventToPaper(); + _enableScrollViewEventRaceFix = RCTExperimentGetScrollViewEventRaceFix(); _childComponentViews = [[NSMutableArray alloc] init]; _scrollView = [[RCTEnhancedScrollView alloc] initWithFrame:self.bounds]; @@ -415,11 +419,16 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView if ((_lastScrollEventDispatchTime == 0) || (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) { _lastScrollEventDispatchTime = now; if (_eventEmitter) { + if (_enableScrollViewEventRaceFix) { + [self _updateStateWithContentOffset]; + } std::static_pointer_cast(_eventEmitter)->onScroll([self _scrollViewMetrics]); } // Once Fabric implements proper NativeAnimationDriver, this should be removed. // This is just a workaround to allow animations based on onScroll event. - RCTSendPaperScrollEvent_DEPRECATED(scrollView, self.tag); + if (_sendScrollEventToPaper) { + RCTSendPaperScrollEvent_DEPRECATED(scrollView, self.tag); + } } [self _remountChildrenIfNeeded]; @@ -622,10 +631,11 @@ - (void)_remountChildren return; } - CGRect visibleFrame = CGRect{_scrollView.contentOffset, _scrollView.bounds.size}; + CGRect visibleFrame = [_scrollView convertRect:_scrollView.bounds toView:_containerView]; visibleFrame = CGRectInset(visibleFrame, -kClippingLeeway, -kClippingLeeway); - CGFloat scale = 1.0 / _scrollView.zoomScale; + // `zoomScale` is negative in RTL. Absolute value is needed. + CGFloat scale = 1.0 / std::abs(_scrollView.zoomScale); visibleFrame.origin.x *= scale; visibleFrame.origin.y *= scale; visibleFrame.size.width *= scale; diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h b/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h index 905844d9f5bcdd..9a814731a9c2e5 100644 --- a/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h @@ -11,6 +11,13 @@ NS_ASSUME_NONNULL_BEGIN @interface RCTAccessibilityElement : UIAccessibilityElement +/* + * Frame of the accessibility element in parent coordinate system. + * Set to `CGRectZero` to use size of the container. + * + * Default value: `CGRectZero`. + */ +@property (nonatomic, assign) CGRect frame; @end NS_ASSUME_NONNULL_END diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm b/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm index 751c1817bad495..d9dcfd73c918a5 100644 --- a/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.mm @@ -12,7 +12,11 @@ @implementation RCTAccessibilityElement - (CGRect)accessibilityFrame { UIView *container = (UIView *)self.accessibilityContainer; - return UIAccessibilityConvertFrameToScreenCoordinates(container.bounds, container); + if (CGRectEqualToRect(_frame, CGRectZero)) { + return UIAccessibilityConvertFrameToScreenCoordinates(container.bounds, container); + } else { + return UIAccessibilityConvertFrameToScreenCoordinates(_frame, container); + } } @end diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm index 08ae2cafa1761d..1048679265d637 100644 --- a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm @@ -57,15 +57,15 @@ - (instancetype)initWithString:(facebook::react::AttributedString)attributedStri // build an array of the accessibleElements NSMutableArray *elements = [NSMutableArray new]; - NSString *accessibilityLabel = [_view valueForKey:@"accessibilityLabel"]; - if (!accessibilityLabel.length) { + NSString *accessibilityLabel = _view.accessibilityLabel; + if (accessibilityLabel.length == 0) { accessibilityLabel = RCTNSStringFromString(_attributedString.getString()); } // add first element has the text for the whole textview in order to read out the whole text - UIAccessibilityElement *firstElement = + RCTAccessibilityElement *firstElement = [[RCTAccessibilityElement alloc] initWithAccessibilityContainer:_view.superview]; firstElement.isAccessibilityElement = YES; - firstElement.accessibilityTraits = UIAccessibilityTraitStaticText; + firstElement.accessibilityTraits = _view.accessibilityTraits; firstElement.accessibilityLabel = accessibilityLabel; firstElement.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(_view.bounds, _view); [firstElement setAccessibilityActivationPoint:CGPointMake( @@ -80,7 +80,11 @@ - (instancetype)initWithString:(facebook::react::AttributedString)attributedStri enumerateAttribute:RCTTextAttributesAccessibilityRoleAttributeName frame:_frame usingBlock:^(CGRect fragmentRect, NSString *_Nonnull fragmentText, NSString *value) { - if (![value isEqualToString:@"button"] && ![value isEqualToString:@"link"]) { + if ([fragmentText isEqualToString:firstElement.accessibilityLabel]) { + // The fragment is the entire paragraph. This is handled as `firstElement`. + return; + } + if ((![value isEqualToString:@"button"] && ![value isEqualToString:@"link"])) { return; } if ([value isEqualToString:@"button"] && @@ -89,8 +93,8 @@ - (instancetype)initWithString:(facebook::react::AttributedString)attributedStri truncatedText = fragmentText; return; } - UIAccessibilityElement *element = - [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self->_view]; + RCTAccessibilityElement *element = + [[RCTAccessibilityElement alloc] initWithAccessibilityContainer:self->_view]; element.isAccessibilityElement = YES; if ([value isEqualToString:@"link"]) { element.accessibilityTraits = UIAccessibilityTraitLink; @@ -100,8 +104,7 @@ - (instancetype)initWithString:(facebook::react::AttributedString)attributedStri numberOfButtons++; } element.accessibilityLabel = fragmentText; - element.accessibilityFrame = - UIAccessibilityConvertFrameToScreenCoordinates(fragmentRect, self->_view); + element.frame = fragmentRect; [elements addObject:element]; }]; diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index f5d280a59e9206..e9e59a9235aa78 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -435,6 +435,14 @@ - (void)setTextAndSelection:(NSInteger)eventCount - (void)setDefaultInputAccessoryView { + // InputAccessoryView component sets the inputAccessoryView when inputAccessoryViewID exists + if (_backedTextInputView.inputAccessoryViewID) { + if (_backedTextInputView.isFirstResponder) { + [_backedTextInputView reloadInputViews]; + } + return; + } + UIKeyboardType keyboardType = _backedTextInputView.keyboardType; // These keyboard types (all are number pads) don't have a "Done" button by default, diff --git a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index 9a302655b69bca..bc34a372f3c10c 100644 --- a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -350,9 +350,7 @@ - (UIView *)betterHitTest:(CGPoint)point withEvent:(UIEvent *)event BOOL clipsToBounds = self.clipsToBounds; - if (RCTExperimentGetOptimizedHitTesting()) { - clipsToBounds = clipsToBounds || _layoutMetrics.overflowInset == EdgeInsets{}; - } + clipsToBounds = clipsToBounds || _layoutMetrics.overflowInset == EdgeInsets{}; if (clipsToBounds && !isPointInside) { return nil; @@ -632,7 +630,7 @@ - (BOOL)shouldGroupAccessibilityChildren NSMutableArray *customActions = [NSMutableArray array]; for (auto const &accessibilityAction : accessibilityActions) { [customActions - addObject:[[UIAccessibilityCustomAction alloc] initWithName:RCTNSStringFromString(accessibilityAction) + addObject:[[UIAccessibilityCustomAction alloc] initWithName:RCTNSStringFromString(accessibilityAction.name) target:self selector:@selector(didActivateAccessibilityCustomAction:)]]; } diff --git a/React/Fabric/Mounting/RCTMountingManager.h b/React/Fabric/Mounting/RCTMountingManager.h index ea1e1d8650cd73..3644f364a04ca1 100644 --- a/React/Fabric/Mounting/RCTMountingManager.h +++ b/React/Fabric/Mounting/RCTMountingManager.h @@ -58,7 +58,9 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)sendAccessibilityEvent:(ReactTag)reactTag eventType:(NSString *)eventType; -- (void)setIsJSResponder:(BOOL)isJSResponder forShadowView:(facebook::react::ShadowView)shadowView; +- (void)setIsJSResponder:(BOOL)isJSResponder + blockNativeResponder:(BOOL)blockNativeResponder + forShadowView:(facebook::react::ShadowView)shadowView; - (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag changedProps:(NSDictionary *)props diff --git a/React/Fabric/Mounting/RCTMountingManager.mm b/React/Fabric/Mounting/RCTMountingManager.mm index b5555757eae4a1..1f6026c913f2e3 100644 --- a/React/Fabric/Mounting/RCTMountingManager.mm +++ b/React/Fabric/Mounting/RCTMountingManager.mm @@ -259,7 +259,9 @@ - (void)performTransaction:(MountingCoordinator::Shared const &)mountingCoordina }); } -- (void)setIsJSResponder:(BOOL)isJSResponder forShadowView:(facebook::react::ShadowView)shadowView +- (void)setIsJSResponder:(BOOL)isJSResponder + blockNativeResponder:(BOOL)blockNativeResponder + forShadowView:(facebook::react::ShadowView)shadowView { RCTExecuteOnMainQueue(^{ UIView *componentView = diff --git a/React/Fabric/RCTScheduler.h b/React/Fabric/RCTScheduler.h index 6eca003c03356b..68353bfea68d8b 100644 --- a/React/Fabric/RCTScheduler.h +++ b/React/Fabric/RCTScheduler.h @@ -35,7 +35,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)schedulerDidSendAccessibilityEvent:(facebook::react::ShadowView const &)shadowView eventType:(std::string const &)eventType; -- (void)schedulerDidSetIsJSResponder:(BOOL)isJSResponder forShadowView:(facebook::react::ShadowView const &)shadowView; +- (void)schedulerDidSetIsJSResponder:(BOOL)isJSResponder + blockNativeResponder:(BOOL)blockNativeResponder + forShadowView:(facebook::react::ShadowView const &)shadowView; @end diff --git a/React/Fabric/RCTScheduler.mm b/React/Fabric/RCTScheduler.mm index 4df385d40b8f57..9de730d92c0681 100644 --- a/React/Fabric/RCTScheduler.mm +++ b/React/Fabric/RCTScheduler.mm @@ -49,7 +49,9 @@ void schedulerDidSetIsJSResponder(ShadowView const &shadowView, bool isJSRespond override { RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_; - [scheduler.delegate schedulerDidSetIsJSResponder:isJSResponder forShadowView:shadowView]; + [scheduler.delegate schedulerDidSetIsJSResponder:isJSResponder + blockNativeResponder:blockNativeResponder + forShadowView:shadowView]; } void schedulerDidSendAccessibilityEvent(const ShadowView &shadowView, std::string const &eventType) override diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index 65c0f185953395..60833131a56f40 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -30,7 +30,9 @@ #import #import #import +#import #import +#import #import #import #import @@ -90,7 +92,6 @@ - (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContai { if (self = [super init]) { assert(contextContainer && "RuntimeExecutor must be not null."); - _runtimeExecutor = runtimeExecutor; _contextContainer = contextContainer; @@ -256,8 +257,12 @@ - (RCTScheduler *)_createScheduler RCTExperimentSetOnDemandViewMounting(YES); } - if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:optimized_hit_testing_ios")) { - RCTExperimentSetOptimizedHitTesting(YES); + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:disable_sending_scroll_events_to_paper")) { + RCTExperimentSetSendScrollEventToPaper(NO); + } + + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_state_scroll_data_race_ios")) { + RCTExperimentSetScrollViewEventRaceFix(YES); } if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:preemptive_view_allocation_disabled_ios")) { @@ -276,7 +281,17 @@ - (RCTScheduler *)_createScheduler auto toolbox = SchedulerToolbox{}; toolbox.contextContainer = _contextContainer; toolbox.componentRegistryFactory = componentRegistryFactory; + + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_runtimescheduler_ios")) { + auto runtimeScheduler = std::make_shared(_runtimeExecutor); + toolbox.runtimeScheduler = runtimeScheduler; + runtimeExecutor = [runtimeScheduler](std::function &&callback) { + runtimeScheduler->scheduleWork(std::move(callback)); + }; + } + toolbox.runtimeExecutor = runtimeExecutor; + toolbox.mainRunLoopObserverFactory = [](RunLoopObserver::Activity activities, RunLoopObserver::WeakOwner const &owner) { return std::make_unique(activities, owner); @@ -286,29 +301,25 @@ - (RCTScheduler *)_createScheduler toolbox.backgroundExecutor = RCTGetBackgroundExecutor(); } -#ifdef REACT_NATIVE_DEBUG - auto optionalBridge = _contextContainer->find>("Bridge"); - if (optionalBridge) { - RCTBridge *bridge = unwrapManagedObjectWeakly(optionalBridge.value()); - toolbox.garbageCollectionTrigger = [bridge]() { - RCTCxxBridge *batchedBridge = (RCTCxxBridge *)([bridge batchedBridge] ?: bridge); - if ([batchedBridge respondsToSelector:@selector(forceGarbageCollection)]) { - [batchedBridge forceGarbageCollection]; - } - }; - } -#endif + toolbox.synchronousEventBeatFactory = + [runtimeExecutor, runtimeScheduler = toolbox.runtimeScheduler](EventBeat::SharedOwnerBox const &ownerBox) { + auto runLoopObserver = + std::make_unique(RunLoopObserver::Activity::BeforeWaiting, ownerBox->owner); + return std::make_unique(std::move(runLoopObserver), runtimeExecutor, runtimeScheduler); + }; - toolbox.synchronousEventBeatFactory = [runtimeExecutor](EventBeat::SharedOwnerBox const &ownerBox) { - auto runLoopObserver = - std::make_unique(RunLoopObserver::Activity::BeforeWaiting, ownerBox->owner); - return std::make_unique(std::move(runLoopObserver), runtimeExecutor); - }; + auto enableV2AsynchronousEventBeat = + reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_asynchronous_event_beat_v2_ios"); - toolbox.asynchronousEventBeatFactory = [runtimeExecutor](EventBeat::SharedOwnerBox const &ownerBox) { + toolbox.asynchronousEventBeatFactory = [runtimeExecutor, enableV2AsynchronousEventBeat]( + EventBeat::SharedOwnerBox const &ownerBox) -> std::unique_ptr { auto runLoopObserver = std::make_unique(RunLoopObserver::Activity::BeforeWaiting, ownerBox->owner); - return std::make_unique(std::move(runLoopObserver), runtimeExecutor); + if (enableV2AsynchronousEventBeat) { + return std::make_unique(std::move(runLoopObserver), runtimeExecutor); + } else { + return std::make_unique(std::move(runLoopObserver), runtimeExecutor); + } }; RCTScheduler *scheduler = [[RCTScheduler alloc] initWithToolbox:toolbox]; @@ -364,9 +375,13 @@ - (void)schedulerDidSendAccessibilityEvent:(const facebook::react::ShadowView &) [self->_mountingManager sendAccessibilityEvent:tag eventType:eventTypeStr]; } -- (void)schedulerDidSetIsJSResponder:(BOOL)isJSResponder forShadowView:(facebook::react::ShadowView const &)shadowView; +- (void)schedulerDidSetIsJSResponder:(BOOL)isJSResponder + blockNativeResponder:(BOOL)blockNativeResponder + forShadowView:(facebook::react::ShadowView const &)shadowView; { - [self->_mountingManager setIsJSResponder:isJSResponder forShadowView:shadowView]; + [self->_mountingManager setIsJSResponder:isJSResponder + blockNativeResponder:blockNativeResponder + forShadowView:shadowView]; } - (void)addObserver:(id)observer diff --git a/React/Modules/RCTEventEmitter.h b/React/Modules/RCTEventEmitter.h index ea7b69c3d8804e..e3bb12f7772229 100644 --- a/React/Modules/RCTEventEmitter.h +++ b/React/Modules/RCTEventEmitter.h @@ -6,13 +6,12 @@ */ #import -#import /** * RCTEventEmitter is an abstract base class to be used for modules that emit * events to be observed by JS. */ -@interface RCTEventEmitter : NSObject +@interface RCTEventEmitter : NSObject @property (nonatomic, weak) RCTBridge *bridge; @property (nonatomic, weak) RCTModuleRegistry *moduleRegistry; diff --git a/React/Modules/RCTEventEmitter.m b/React/Modules/RCTEventEmitter.m index c3cc596e13ca18..20af19f91a5dbf 100644 --- a/React/Modules/RCTEventEmitter.m +++ b/React/Modules/RCTEventEmitter.m @@ -15,7 +15,7 @@ @implementation RCTEventEmitter { BOOL _observationDisabled; } -@synthesize invokeJS = _invokeJS; +@synthesize callableJSModules = _callableJSModules; + (NSString *)moduleName { @@ -48,10 +48,10 @@ - (instancetype)initWithDisabledObservation - (void)sendEventWithName:(NSString *)eventName body:(id)body { RCTAssert( - _bridge != nil || _invokeJS != nil, + _callableJSModules != nil, @"Error when sending event: %@ with body: %@. " - "Bridge is not set. This is probably because you've " - "explicitly synthesized the bridge in %@, even though it's inherited " + "RCTCallableJSModules is not set. This is probably because you've " + "explicitly synthesized the RCTCallableJSModules in %@, even though it's inherited " "from RCTEventEmitter.", eventName, body, @@ -67,13 +67,10 @@ - (void)sendEventWithName:(NSString *)eventName body:(id)body BOOL shouldEmitEvent = (_observationDisabled || _listenerCount > 0); - if (shouldEmitEvent && _bridge) { - [_bridge enqueueJSCall:@"RCTDeviceEventEmitter" - method:@"emit" - args:body ? @[ eventName, body ] : @[ eventName ] - completion:NULL]; - } else if (shouldEmitEvent && _invokeJS) { - _invokeJS(@"RCTDeviceEventEmitter", @"emit", body ? @[ eventName, body ] : @[ eventName ]); + if (shouldEmitEvent && _callableJSModules) { + [_callableJSModules invokeModule:@"RCTDeviceEventEmitter" + method:@"emit" + withArgs:body ? @[ eventName, body ] : @[ eventName ]]; } else { RCTLogWarn(@"Sending `%@` with no listeners registered.", eventName); } diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index fddcb5ce7ccc48..58f6a4afd10eef 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -147,6 +147,8 @@ - (NSMapTable *)nativeIDRegistry - (void)setBridge:(RCTBridge *)bridge { + RCTEnforceNotAllowedForNewArchitecture(self, @"RCTUIManager must not be initialized for the new architecture"); + RCTAssert(_bridge == nil, @"Should not re-use same UIManager instance"); _bridge = bridge; diff --git a/React/React-RCTFabric.podspec b/React/React-RCTFabric.podspec index 3974d2a7cc432f..b6fceebb3dd674 100644 --- a/React/React-RCTFabric.podspec +++ b/React/React-RCTFabric.podspec @@ -18,7 +18,7 @@ end folly_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1' folly_compiler_flags = folly_flags + ' ' + '-Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' Pod::Spec.new do |s| diff --git a/React/Tests/Text/RCTParagraphComponentViewTests.mm b/React/Tests/Text/RCTParagraphComponentViewTests.mm index 4bc04029269f14..e847ef76f2f423 100644 --- a/React/Tests/Text/RCTParagraphComponentViewTests.mm +++ b/React/Tests/Text/RCTParagraphComponentViewTests.mm @@ -404,4 +404,67 @@ - (void)testAccessibilityTruncatedText @"Expected the second accessibilityElement has link trait"); } +- (void)testEntireParagraphLink +{ + std::shared_ptr rootShadowNode; + std::shared_ptr paragrahShadowNode; + + auto element = Element() + .reference(rootShadowNode) + .tag(1) + .props([] { + auto sharedProps = std::make_shared(); + auto &props = *sharedProps; + props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}}; + auto &yogaStyle = props.yogaStyle; + yogaStyle.dimensions()[YGDimensionWidth] = YGValue{200, YGUnitPoint}; + yogaStyle.dimensions()[YGDimensionHeight] = YGValue{200, YGUnitPoint}; + return sharedProps; + }) + .children({ + Element() + .reference(paragrahShadowNode) + .props([] { + auto sharedProps = std::make_shared(); + auto &props = *sharedProps; + props.accessible = true; + props.accessibilityTraits = AccessibilityTraits::Link; + auto &yogaStyle = props.yogaStyle; + yogaStyle.positionType() = YGPositionTypeAbsolute; + yogaStyle.position()[YGEdgeLeft] = YGValue{0, YGUnitPoint}; + yogaStyle.position()[YGEdgeTop] = YGValue{0, YGUnitPoint}; + yogaStyle.dimensions()[YGDimensionWidth] = YGValue{200, YGUnitPoint}; + yogaStyle.dimensions()[YGDimensionHeight] = YGValue{20, YGUnitPoint}; + return sharedProps; + }) + .children({ + Element() + .props([] { + auto sharedProps = std::make_shared(); + auto &props = *sharedProps; + props.textAttributes.accessibilityRole = AccessibilityRole::Link; + return sharedProps; + }) + .children({Element().reference(RawTextShadowNodeABA_).props([] { + auto sharedProps = std::make_shared(); + auto &props = *sharedProps; + props.text = "A long text that happens to be a link"; + return sharedProps; + })}), + }), + }); + + builder_->build(element); + rootShadowNode->layoutIfNeeded(); + + ParagraphShadowNode::ConcreteState::Shared _state = stateWithShadowNode(paragrahShadowNode); + RCTParagraphComponentView *paragraphComponentView = [[RCTParagraphComponentView alloc] init]; + [paragraphComponentView updateProps:paragrahShadowNode->getProps() oldProps:nullptr]; + [paragraphComponentView updateState:_state oldState:nil]; + + NSArray *elements = paragraphComponentView.accessibilityElements; + XCTAssertEqual(elements.count, 1); + XCTAssertTrue(elements[0].accessibilityTraits & UIAccessibilityTraitLink); +} + @end diff --git a/React/Views/RCTDatePickerManager.m b/React/Views/RCTDatePickerManager.m index 38f662463f6b3a..f6fec6d739f17a 100644 --- a/React/Views/RCTDatePickerManager.m +++ b/React/Views/RCTDatePickerManager.m @@ -25,6 +25,21 @@ @implementation RCTConvert (UIDatePicker) UIDatePickerModeTime, integerValue) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + +RCT_ENUM_CONVERTER( + UIDatePickerStyle, + (@{ + @"compact" : @(UIDatePickerStyleCompact), + @"spinner" : @(UIDatePickerStyleWheels), + @"inline" : @(UIDatePickerStyleInline), + }), + UIDatePickerStyleAutomatic, + integerValue) +#endif +#pragma clang diagnostic pop @end @implementation RCTDatePickerManager @@ -66,4 +81,22 @@ - (UIView *)view }]; } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 +RCT_CUSTOM_VIEW_PROPERTY(pickerStyle, UIDatePickerStyle, RCTDatePicker) +{ + if (@available(iOS 14, *)) { + // If the style changed, then the date picker may need to be resized and will generate a layout pass to display + // correctly. We need to prevent that to get consistent layout. That's why we memorise the old frame and set it + // after style is changed. + CGRect oldFrame = view.frame; + if (json) { + UIDatePickerStyle style = [RCTConvert UIDatePickerStyle:json]; + view.preferredDatePickerStyle = style; + } else { + view.preferredDatePickerStyle = UIDatePickerStyleWheels; + } + view.frame = oldFrame; + } +} +#endif @end diff --git a/React/Views/RCTModalHostView.h b/React/Views/RCTModalHostView.h index c54c1c69c94413..880b24c9a48d46 100644 --- a/React/Views/RCTModalHostView.h +++ b/React/Views/RCTModalHostView.h @@ -23,6 +23,7 @@ @property (nonatomic, assign, getter=isTransparent) BOOL transparent; @property (nonatomic, copy) RCTDirectEventBlock onShow; +@property (nonatomic, assign) BOOL visible; @property (nonatomic, copy) NSNumber *identifier; @@ -31,6 +32,9 @@ @property (nonatomic, copy) NSArray *supportedOrientations; @property (nonatomic, copy) RCTDirectEventBlock onOrientationChange; +// Fabric only +@property (nonatomic, copy) RCTBubblingEventBlock onDismiss; + - (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER; @end diff --git a/React/Views/RCTModalHostView.m b/React/Views/RCTModalHostView.m index 0cfa69a99aab6f..fa9aae7a2c14f0 100644 --- a/React/Views/RCTModalHostView.m +++ b/React/Views/RCTModalHostView.m @@ -119,31 +119,13 @@ - (void)didMoveToWindow return; } - if (!_isPresented && self.window) { - RCTAssert(self.reactViewController, @"Can't present modal view controller without a presenting view controller"); - - _modalViewController.supportedInterfaceOrientations = [self supportedOrientationsMask]; - - if ([self.animationType isEqualToString:@"fade"]) { - _modalViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - } else if ([self.animationType isEqualToString:@"slide"]) { - _modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; - } - if (self.presentationStyle != UIModalPresentationNone) { - _modalViewController.modalPresentationStyle = self.presentationStyle; - } - [_delegate presentModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]]; - _isPresented = YES; - } + [self ensurePresentedOnlyIfNeeded]; } - (void)didMoveToSuperview { [super didMoveToSuperview]; - - if (_isPresented && !self.superview) { - [self dismissModalViewController]; - } + [self ensurePresentedOnlyIfNeeded]; } - (void)invalidate @@ -163,6 +145,40 @@ - (BOOL)hasAnimationType return ![self.animationType isEqualToString:@"none"]; } +- (void)setVisible:(BOOL)visible +{ + if (_visible != visible) { + _visible = visible; + [self ensurePresentedOnlyIfNeeded]; + } +} + +- (void)ensurePresentedOnlyIfNeeded +{ + BOOL shouldBePresented = !_isPresented && _visible && self.window; + if (shouldBePresented) { + RCTAssert(self.reactViewController, @"Can't present modal view controller without a presenting view controller"); + + _modalViewController.supportedInterfaceOrientations = [self supportedOrientationsMask]; + + if ([self.animationType isEqualToString:@"fade"]) { + _modalViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + } else if ([self.animationType isEqualToString:@"slide"]) { + _modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; + } + if (self.presentationStyle != UIModalPresentationNone) { + _modalViewController.modalPresentationStyle = self.presentationStyle; + } + [_delegate presentModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]]; + _isPresented = YES; + } + + BOOL shouldBeHidden = _isPresented && (!_visible || !self.superview); + if (shouldBeHidden) { + [self dismissModalViewController]; + } +} + - (void)setTransparent:(BOOL)transparent { if (self.isTransparent != transparent) { diff --git a/React/Views/RCTModalHostViewManager.m b/React/Views/RCTModalHostViewManager.m index 91d83aabbdc604..7ca197d5866f7c 100644 --- a/React/Views/RCTModalHostViewManager.m +++ b/React/Views/RCTModalHostViewManager.m @@ -120,5 +120,9 @@ - (void)invalidate RCT_EXPORT_VIEW_PROPERTY(identifier, NSNumber) RCT_EXPORT_VIEW_PROPERTY(supportedOrientations, NSArray) RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(visible, BOOL) + +// Fabric only +RCT_EXPORT_VIEW_PROPERTY(onDismiss, RCTDirectEventBlock) @end diff --git a/React/Views/RCTModalManager.h b/React/Views/RCTModalManager.h index a34d801448c191..4fbe6dfbd01e25 100644 --- a/React/Views/RCTModalManager.h +++ b/React/Views/RCTModalManager.h @@ -7,7 +7,6 @@ #import -#import #import #import @@ -16,9 +15,3 @@ - (void)modalDismissed:(NSNumber *)modalID; @end - -@interface RCTBridge (RCTModalManager) - -@property (nonatomic, readonly) RCTModalManager *modalManager; - -@end diff --git a/React/Views/RCTModalManager.m b/React/Views/RCTModalManager.m index 399c025a161e30..992b73c62db660 100644 --- a/React/Views/RCTModalManager.m +++ b/React/Views/RCTModalManager.m @@ -40,12 +40,3 @@ - (void)modalDismissed:(NSNumber *)modalID } @end - -@implementation RCTBridge (RCTDevSettings) - -- (RCTModalManager *)modalManager -{ - return [self moduleForClass:[RCTModalManager class]]; -} - -@end diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index 48dcd0a06ce4a3..36f8851f04a570 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -7,6 +7,7 @@ #import "RCTViewManager.h" +#import "RCTAssert.h" #import "RCTBorderStyle.h" #import "RCTBridge.h" #import "RCTConvert+Transform.h" @@ -26,6 +27,7 @@ @implementation RCTConvert (UIAccessibilityTraits) (@{ @"none" : @(UIAccessibilityTraitNone), @"button" : @(UIAccessibilityTraitButton), + @"togglebutton" : @(UIAccessibilityTraitButton), @"link" : @(UIAccessibilityTraitLink), @"header" : @(UIAccessibilityTraitHeader), @"search" : @(UIAccessibilityTraitSearchField), @@ -76,6 +78,12 @@ - (dispatch_queue_t)methodQueue return RCTGetUIManagerQueue(); } +- (void)setBridge:(RCTBridge *)bridge +{ + RCTWarnNotAllowedForNewArchitecture(self, @"RCTViewManager must not be initialized for the new architecture"); + _bridge = bridge; +} + - (UIView *)view { return [RCTView new]; @@ -293,6 +301,13 @@ - (RCTShadowView *)shadowView } } +RCT_CUSTOM_VIEW_PROPERTY(collapsable, BOOL, RCTView) +{ + // Property is only to be used in the new renderer. + // It is necessary to add it here, otherwise it gets + // filtered by view configs. +} + #define RCT_VIEW_BORDER_PROPERTY(SIDE) \ RCT_CUSTOM_VIEW_PROPERTY(border##SIDE##Width, float, RCTView) \ { \ diff --git a/React/third-party.xcconfig b/React/third-party.xcconfig index ada55f5ebe8ce0..579c50314c0665 100644 --- a/React/third-party.xcconfig +++ b/React/third-party.xcconfig @@ -8,5 +8,5 @@ // LICENSE file in the root directory of this source tree. // -HEADER_SEARCH_PATHS = $(SRCROOT)/../third-party/boost_1_63_0 $(SRCROOT)/../third-party/folly-2020.01.13.00 $(SRCROOT)/../third-party/glog-0.3.5/src +HEADER_SEARCH_PATHS = $(SRCROOT)/../third-party/boost_1_63_0 $(SRCROOT)/../third-party/folly-2021.04.26.00 $(SRCROOT)/../third-party/glog-0.3.5/src OTHER_CFLAGS = -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 diff --git a/ReactAndroid/README.md b/ReactAndroid/README.md index a920b7615d9b0e..89a61dab6298bc 100644 --- a/ReactAndroid/README.md +++ b/ReactAndroid/README.md @@ -4,4 +4,4 @@ See the [docs on the website](https://reactnative.dev/docs/building-from-source. # Running tests -When you submit a pull request CircleCI will automatically run all tests. To run tests locally, see [Testing](https://reactnative.dev/docs/testing.html). +When you submit a pull request CircleCI will automatically run all tests. To run tests locally, see [Testing](https://github.com/facebook/react-native/wiki/Tests). diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index ee51e20d245488..da85f3423f6b0e 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -56,7 +56,8 @@ task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) { task prepareBoost(dependsOn: boostPath ? [] : [downloadBoost], type: Copy) { from(boostPath ?: tarTree(resources.gzip(downloadBoost.dest))) from("src/main/jni/third-party/boost/Android.mk") - include("Android.mk", "boost_${BOOST_VERSION}/boost/**/*.hpp", "boost/boost/**/*.hpp") + from("src/main/jni/third-party/boost") + include("Android.mk", "boost_${BOOST_VERSION}/boost/**/*.hpp", "boost/boost/**/*.hpp", "asm/**/*.S") includeEmptyDirs = false into("$thirdPartyNdkDir/boost") doLast { @@ -96,6 +97,51 @@ task prepareFolly(dependsOn: dependenciesPath ? [] : [downloadFolly], type: Copy into("$thirdPartyNdkDir/folly") } +task downloadFmt(dependsOn: createNativeDepsDirectories, type: Download) { + src("https://github.com/fmtlib/fmt/archive/${FMT_VERSION}.tar.gz") + onlyIfNewer(true) + overwrite(false) + dest(new File(downloadsDir, "fmt-${FMT_VERSION}.tar.gz")) +} + +task prepareFmt(dependsOn: dependenciesPath ? [] : [downloadFmt], type: Copy) { + from(dependenciesPath ?: tarTree(downloadFmt.dest)) + from("src/main/jni/third-party/fmt/Android.mk") + include("fmt-${FMT_VERSION}/src/**/*", "fmt-${FMT_VERSION}/include/**/*", "Android.mk") + eachFile { fname -> fname.path = (fname.path - "fmt-${FMT_VERSION}/") } + includeEmptyDirs = false + into("$thirdPartyNdkDir/fmt") +} + +task downloadLibevent(dependsOn: createNativeDepsDirectories, type: Download) { + src("https://github.com/libevent/libevent/releases/download/release-${LIBEVENT_VERSION}-stable/libevent-${LIBEVENT_VERSION}-stable.tar.gz") + onlyIfNewer(true) + overwrite(false) + dest(new File(downloadsDir, "libevent-${LIBEVENT_VERSION}.tar.gz")) +} + +task prepareLibevent(dependsOn: dependenciesPath ? [] : [downloadLibevent], type: Copy) { + from(dependenciesPath ?: tarTree(downloadLibevent.dest)) + from("src/main/jni/third-party/libevent/Android.mk") + from("src/main/jni/third-party/libevent/event-config.h") + from("src/main/jni/third-party/libevent/evconfig-private.h") + include( + "libevent-${LIBEVENT_VERSION}-stable/*.c", + "libevent-${LIBEVENT_VERSION}-stable/*.h", + "libevent-${LIBEVENT_VERSION}-stable/include/**/*", + "evconfig-private.h", + "event-config.h", + "Android.mk" + ) + eachFile { fname -> fname.path = (fname.path - "libevent-${LIBEVENT_VERSION}-stable/") } + includeEmptyDirs = false + into("$thirdPartyNdkDir/libevent") + + doLast { + ant.move(file: "$thirdPartyNdkDir/libevent/event-config.h", tofile: "$thirdPartyNdkDir/libevent/include/event2/event-config.h") + } +} + task prepareHermes(dependsOn: createNativeDepsDirectories, type: Copy) { def hermesPackagePath = findNodeModulePath(projectDir, "hermes-engine") if (!hermesPackagePath) { @@ -196,6 +242,8 @@ task downloadNdkBuildDependencies { dependsOn(downloadDoubleConversion) dependsOn(downloadFolly) dependsOn(downloadGlog) + dependsOn(downloadFmt) + dependsOn(downloadLibevent) } /** @@ -297,7 +345,7 @@ def getNdkBuildFullPath() { } def buildReactNdkLib = tasks.register("buildReactNdkLib", Exec) { - dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFolly, prepareGlog, extractAARHeaders, extractJNIFiles) + dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFmt, prepareFolly, prepareGlog, prepareLibevent, extractAARHeaders, extractJNIFiles) dependsOn("generateCodegenArtifactsFromSchema"); inputs.dir("$projectDir/../ReactCommon") diff --git a/ReactAndroid/gradle.properties b/ReactAndroid/gradle.properties index d527714819e598..ffc22de2891222 100644 --- a/ReactAndroid/gradle.properties +++ b/ReactAndroid/gradle.properties @@ -17,7 +17,9 @@ SO_LOADER_VERSION=0.9.0 BOOST_VERSION=1_63_0 DOUBLE_CONVERSION_VERSION=1.1.6 -FOLLY_VERSION=2020.01.13.00 +FOLLY_VERSION=2021.04.26.00 +FMT_VERSION=6.2.1 +LIBEVENT_VERSION=2.1.12 GLOG_VERSION=0.3.5 android.useAndroidX=true diff --git a/ReactAndroid/src/androidTest/js/UIManagerTestModule.js b/ReactAndroid/src/androidTest/js/UIManagerTestModule.js index 61b0d0b2f384dd..25c7c5e0cc75c1 100644 --- a/ReactAndroid/src/androidTest/js/UIManagerTestModule.js +++ b/ReactAndroid/src/androidTest/js/UIManagerTestModule.js @@ -16,6 +16,7 @@ const React = require('react'); const renderApplication = require('react-native/Libraries/ReactNative/renderApplication'); const {StyleSheet, Text, View} = require('react-native'); +import type {RootTag} from 'react-native/Libraries/Types/RootTagTypes'; type FlexTestAppProps = $ReadOnly<{||}>; class FlexTestApp extends React.Component { @@ -234,26 +235,26 @@ const UpdatePositionInListTestAppStyles = StyleSheet.create({ const emptyExactProps = Object.freeze({}); const UIManagerTestModule = { - renderFlexTestApplication(rootTag: number) { + renderFlexTestApplication(rootTag: RootTag) { renderApplication(FlexTestApp, emptyExactProps, rootTag); }, - renderFlexWithTextApplication(rootTag: number) { + renderFlexWithTextApplication(rootTag: RootTag) { renderApplication(FlexWithText, emptyExactProps, rootTag); }, - renderAbsolutePositionBottomRightTestApplication(rootTag: number) { + renderAbsolutePositionBottomRightTestApplication(rootTag: RootTag) { renderApplication( AbsolutePositionBottomRightTestApp, emptyExactProps, rootTag, ); }, - renderAbsolutePositionTestApplication(rootTag: number) { + renderAbsolutePositionTestApplication(rootTag: RootTag) { renderApplication(AbsolutePositionTestApp, emptyExactProps, rootTag); }, - renderCenteredTextViewTestApplication(rootTag: number, text: string) { + renderCenteredTextViewTestApplication(rootTag: RootTag, text: string) { renderApplication(CenteredTextView, {text: text}, rootTag); }, - renderUpdatePositionInListTestApplication(rootTag: number) { + renderUpdatePositionInListTestApplication(rootTag: RootTag) { renderApplication(UpdatePositionInListTestApp, emptyExactProps, rootTag); }, flushUpdatePositionInList, diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 2b97586881aec9..2b0d89aa19adbc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -318,9 +318,8 @@ public JavaScriptExecutorFactory getJavaScriptExecutorFactory() { Activity currentActivity = getCurrentActivity(); if (currentActivity != null) { ReactRootView rootView = new ReactRootView(currentActivity); - + rootView.setIsFabric(ReactFeatureFlags.enableFabricInLogBox); rootView.startReactApplication(ReactInstanceManager.this, appKey, null); - return rootView; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java index 9d6f4299db2ba3..dd7a0c1b2f3c0d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java @@ -118,7 +118,6 @@ public long getBatchNumber() { private boolean mBatchingControlledByJS = false; // TODO T71377544: delete private volatile long mCurrentFrameNumber; // TODO T71377544: delete private volatile long mCurrentBatchNumber; - private volatile boolean mIsInBatch = false; private boolean mInitializedForFabric = false; private boolean mInitializedForNonFabric = false; @@ -174,7 +173,7 @@ public void onHostResume() { } private void addOperation(UIThreadOperation operation) { - operation.setBatchNumber(mIsInBatch ? mCurrentBatchNumber : -1); + operation.setBatchNumber(mCurrentBatchNumber); mOperations.add(operation); } @@ -184,7 +183,7 @@ private void addUnbatchedOperation(UIThreadOperation operation) { } private void addPreOperation(UIThreadOperation operation) { - operation.setBatchNumber(mIsInBatch ? mCurrentBatchNumber : -1); + operation.setBatchNumber(mCurrentBatchNumber); mPreOperations.add(operation); } @@ -427,14 +426,12 @@ private void decrementInFlightAnimationsForViewTag(final int viewTag) { @Override public void startOperationBatch() { mBatchingControlledByJS = true; - mIsInBatch = true; mCurrentBatchNumber++; } @Override public void finishOperationBatch() { mBatchingControlledByJS = true; - mIsInBatch = false; mCurrentBatchNumber++; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java index 0ff510e5d0d234..08dc3a7c262609 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java @@ -535,7 +535,7 @@ private void handleEvent(Event event) { return; } UIManager uiManager = - UIManagerHelper.getUIManagerForReactTag(mReactApplicationContext, event.getViewTag()); + UIManagerHelper.getUIManager(mReactApplicationContext, event.getUIManagerType()); if (uiManager == null) { return; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java index cdc1eb26a3699a..c0d8d225e31243 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java @@ -550,7 +550,11 @@ public JavaScriptContextHolder getJavaScriptContextHolder() { } @Override - public native RuntimeExecutor getRuntimeExecutor(); + public RuntimeExecutor getRuntimeExecutor() { + return getRuntimeExecutor(ReactFeatureFlags.enableRuntimeExecutorFlushing()); + } + + public native RuntimeExecutor getRuntimeExecutor(boolean shouldFlush); @Override public void addJSIModules(List jsiModules) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java index f227f0da0629ba..9caaeff3508c34 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java @@ -63,6 +63,7 @@ public class ReactContext extends ContextWrapper { private @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler; private @Nullable NativeModuleCallExceptionHandler mExceptionHandlerWrapper; private @Nullable WeakReference mCurrentActivity; + private boolean mIsInitialized = false; public ReactContext(Context base) { super(base); @@ -101,6 +102,18 @@ public void initializeMessageQueueThreads(ReactQueueConfiguration queueConfig) { mUiMessageQueueThread = queueConfig.getUIQueueThread(); mNativeModulesMessageQueueThread = queueConfig.getNativeModulesQueueThread(); mJSMessageQueueThread = queueConfig.getJSQueueThread(); + + /** TODO(T85807990): Fail fast if any of the threads is null. */ + if (mUiMessageQueueThread == null) { + throw new IllegalStateException("UI thread is null"); + } + if (mNativeModulesMessageQueueThread == null) { + throw new IllegalStateException("NativeModules thread is null"); + } + if (mJSMessageQueueThread == null) { + throw new IllegalStateException("JavaScript thread is null"); + } + mIsInitialized = true; } public void resetPerfStats() { @@ -352,10 +365,20 @@ public void runOnUiQueueThread(Runnable runnable) { } public void assertOnNativeModulesQueueThread() { + /** TODO(T85807990): Fail fast if the ReactContext isn't initialized */ + if (!mIsInitialized) { + throw new IllegalStateException( + "Tried to call assertOnNativeModulesQueueThread() on an uninitialized ReactContext"); + } Assertions.assertNotNull(mNativeModulesMessageQueueThread).assertIsOnThread(); } public void assertOnNativeModulesQueueThread(String message) { + /** TODO(T85807990): Fail fast if the ReactContext isn't initialized */ + if (!mIsInitialized) { + throw new IllegalStateException( + "Tried to call assertOnNativeModulesQueueThread(message) on an uninitialized ReactContext"); + } Assertions.assertNotNull(mNativeModulesMessageQueueThread).assertIsOnThread(message); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java index a0395cb6113e66..4c19185c725215 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java @@ -119,5 +119,7 @@ public enum ReactMarkerConstants { REACT_BRIDGE_LOADING_START, REACT_BRIDGE_LOADING_END, REACT_BRIDGELESS_LOADING_START, - REACT_BRIDGELESS_LOADING_END + REACT_BRIDGELESS_LOADING_END, + LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_START, + LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_END, } diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/BUCK b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/BUCK index 58366da207e166..a552d6027fe00b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/BUCK @@ -21,6 +21,9 @@ rn_android_library( react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/java/infer-annotations:infer-annotations"), react_native_target("java/com/facebook/react/common:common"), + # dependencies used for systraces + react_native_dep("java/com/facebook/systrace:systrace"), + react_native_target("java/com/facebook/react/bridge:bridge"), ], exported_deps = [], ) diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java index e70c3c090cc7e9..f38ae42b07ad70 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java +++ b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java @@ -10,7 +10,6 @@ import androidx.annotation.Nullable; import com.facebook.jni.HybridData; import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.soloader.SoLoader; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Iterator; @@ -23,14 +22,14 @@ public class ReadableMapBuffer implements Iterable { static { - SoLoader.loadLibrary("mapbufferjni"); + ReadableMapBufferSoLoader.staticInit(); } // Value used to verify if the data is serialized with LittleEndian order. private static final int ALIGNMENT = 0xFE; - // 6 bytes = 2 (alignment) + 2 (count) + 2 (size) - private static final int HEADER_SIZE = 6; + // 8 bytes = 2 (alignment) + 2 (count) + 4 (size) + private static final int HEADER_SIZE = 8; // key size = 2 bytes private static final int KEY_SIZE = 2; @@ -50,7 +49,7 @@ public class ReadableMapBuffer implements Iterable ReadableMapBuffer::importByteBufferAllocateDirect() { - // TODO: Using this method is safer than "importByteBuffer" because ByteBuffer - // memory will be deallocated once the "Java ByteBuffer" is deallocated. Next - // steps: + // TODO T83483191: Using this method is safer than "importByteBuffer" because + // ByteBuffer memory will be deallocated once the "Java ByteBuffer" is + // deallocated. Next steps: // - Validate perf of this method vs importByteBuffer // - Validate that there's no leaking of memory - return jni::JByteBuffer::allocateDirect(_serializedDataSize); + react_native_assert( + (serializedData_ != nullptr && serializedDataSize_ != 0) && + "Error serializedData_ is not initialized"); + auto ret = jni::JByteBuffer::allocateDirect(serializedDataSize_); + // TODO T83483191: avoid allocating serializedData_ when using + // JByteBuffer::allocateDirect + std::memcpy( + ret->getDirectBytes(), (void *)serializedData_, serializedDataSize_); + + // Deallocate serializedData_ since it's not necessary anymore + delete[] serializedData_; + serializedData_ = nullptr; + serializedDataSize_ = 0; + return ret; } jni::JByteBuffer::javaobject ReadableMapBuffer::importByteBuffer() { - // TODO: Reevaluate what's the best approach here (allocateDirect vs + // TODO T83483191: Reevaluate what's the best approach here (allocateDirect vs // DirectByteBuffer). // // On this method we should: @@ -44,7 +57,7 @@ jni::JByteBuffer::javaobject ReadableMapBuffer::importByteBuffer() { // transfer data of multitple Maps return static_cast( jni::Environment::current()->NewDirectByteBuffer( - (void *)_serializedData, _serializedDataSize)); + (void *)serializedData_, serializedDataSize_)); } jni::local_ref @@ -53,9 +66,10 @@ ReadableMapBuffer::createWithContents(MapBuffer &&map) { } ReadableMapBuffer::~ReadableMapBuffer() { - delete[] _serializedData; - _serializedData = nullptr; - _serializedDataSize = 0; + if (serializedData_ != nullptr) { + delete[] serializedData_; + serializedData_ = nullptr; + } } } // namespace react diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/react/common/mapbuffer/ReadableMapBuffer.h b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/react/common/mapbuffer/ReadableMapBuffer.h index 555851199f563c..b3f753a67b1711 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/react/common/mapbuffer/ReadableMapBuffer.h +++ b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/jni/react/common/mapbuffer/ReadableMapBuffer.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include @@ -31,16 +32,18 @@ class ReadableMapBuffer : public jni::HybridClass { ~ReadableMapBuffer(); private: - uint8_t *_serializedData = nullptr; + uint8_t *serializedData_ = nullptr; - int _serializedDataSize = 0; + int32_t serializedDataSize_ = 0; friend HybridBase; explicit ReadableMapBuffer(MapBuffer &&map) { - _serializedDataSize = map.getBufferSize(); - _serializedData = new Byte[_serializedDataSize]; - map.copy(_serializedData); + serializedDataSize_ = map.getBufferSize(); + react_native_assert( + (serializedDataSize_ != 0) && "Error no content in map"); + serializedData_ = new Byte[serializedDataSize_]; + map.copy(serializedData_); } }; diff --git a/ReactAndroid/src/main/java/com/facebook/react/config/BUCK b/ReactAndroid/src/main/java/com/facebook/react/config/BUCK index d2a96d88cfeeea..f5ea5a7dd8065b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/config/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/config/BUCK @@ -1,4 +1,4 @@ -load("//tools/build_defs/oss:rn_defs.bzl", "rn_android_library") +load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_library") rn_android_library( name = "config", @@ -9,5 +9,6 @@ rn_android_library( "PUBLIC", ], deps = [ + react_native_dep("java/com/facebook/proguard/annotations:annotations"), ], ) diff --git a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index 8416fe580fffcc..4f187da35576fe 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -7,6 +7,8 @@ package com.facebook.react.config; +import com.facebook.proguard.annotations.DoNotStripAny; + /** * Hi there, traveller! This configuration class is not meant to be used by end-users of RN. It * contains mainly flags for features that are either under active development and not ready for @@ -14,8 +16,14 @@ * *

These values are safe defaults and should not require manual changes. */ +@DoNotStripAny public class ReactFeatureFlags { + /** An interface used to compute flags on demand. */ + public interface FlagProvider { + boolean get(); + } + /** * Should this application use TurboModules? If yes, then any module that inherits {@link * com.facebook.react.turbomodule.core.interfaces.TurboModule} will NOT be passed in to C++ @@ -33,34 +41,15 @@ public class ReactFeatureFlags { /** Should we dispatch TurboModule methods with promise returns to the NativeModules thread? */ public static volatile boolean enableTurboModulePromiseAsyncDispatch = false; - /* - * This feature flag enables logs for Fabric - */ + /** This feature flag enables logs for Fabric */ public static boolean enableFabricLogs = false; - /** - * Should this application use a {@link com.facebook.react.uimanager.ViewManagerDelegate} (if - * provided) to update the view properties. If {@code false}, then the generated {@code - * ...$$PropsSetter} class will be used instead. - */ - public static boolean useViewManagerDelegates = false; - - /** - * Should this application use a {@link com.facebook.react.uimanager.ViewManagerDelegate} (if - * provided) to execute the view commands. If {@code false}, then {@code receiveCommand} method - * inside view manager will be called instead. - */ - public static boolean useViewManagerDelegatesForCommands = false; - - /** - * Temporary feature flat to control a fix in the transition to layoutOnlyViews TODO T61185028: - * remove this when bug is fixed - */ - public static boolean enableTransitionLayoutOnlyViewCleanup = false; - /** Feature flag to configure eager initialization of Fabric */ public static boolean eagerInitializeFabric = false; + /** Feature flag to configure eager initialization classes of Fabric */ + public static boolean eagerInitializeFabricClasses = false; + /** Enables Static ViewConfig in RN Android native code. */ public static boolean enableExperimentalStaticViewConfigs = false; @@ -70,6 +59,50 @@ public class ReactFeatureFlags { /** Enables JS Responder in Fabric */ public static boolean enableJSResponder = false; - /** Enables MapBuffer Serialization */ - public static boolean mapBufferSerializationEnabled = false; + /** Feature flag to configure eager initialization of MapBuffer So file */ + public static boolean enableEagerInitializeMapBufferSoFile = false; + + /** Should the RuntimeExecutor call JSIExecutor::flush()? */ + private static FlagProvider enableRuntimeExecutorFlushingProvider = null; + + public static void setEnableRuntimeExecutorFlushingFlagProvider(FlagProvider provider) { + enableRuntimeExecutorFlushingProvider = provider; + } + + private static boolean mapBufferSerializationEnabled = false; + + /** Enables or disables MapBuffer Serialization */ + public static void setMapBufferSerializationEnabled(boolean enabled) { + mapBufferSerializationEnabled = enabled; + } + + public static boolean isMapBufferSerializationEnabled() { + return mapBufferSerializationEnabled; + } + + public static boolean enableRuntimeExecutorFlushing() { + if (enableRuntimeExecutorFlushingProvider != null) { + return enableRuntimeExecutorFlushingProvider.get(); + } + + return false; + } + + /** Enables Fabric for LogBox */ + public static boolean enableFabricInLogBox = false; + + public static boolean enableLockFreeEventDispatcher = false; + + // + // ScrollView C++ UpdateState vs onScroll race fixes + // + + /* Enables a "state race condition fix" for ScrollViews StateUpdate + onScroll event emitter */ + public static boolean enableScrollViewStateEventRaceFix = false; + + /* Enables another "state race condition fix" for ScrollViews StateUpdate + onScroll event emitter. Races a StateUpdate with every onScroll event. */ + public static boolean enableScrollViewStateEventAlwaysRace = false; + + /* Configure a min scroll delta for UpdateState to be called while still actively scrolling. */ + public static int scrollViewUpdateStateMinScrollDelta = 0; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java index 27382dbef01f53..65487b6e053195 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java @@ -15,11 +15,16 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.UIManager; import com.facebook.react.bridge.queue.MessageQueueThread; +import com.facebook.react.common.mapbuffer.ReadableMapBuffer; +import com.facebook.react.common.mapbuffer.ReadableMapBufferSoLoader; +import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.fabric.events.EventBeatManager; import com.facebook.react.fabric.events.EventEmitterWrapper; import com.facebook.react.fabric.events.FabricEventEmitter; import com.facebook.react.fabric.mounting.LayoutMetricsConversions; +import com.facebook.react.fabric.mounting.MountItemDispatcher; import com.facebook.react.fabric.mounting.MountingManager; +import com.facebook.react.fabric.mounting.SurfaceMountingManager; import com.facebook.react.fabric.mounting.mountitems.DispatchCommandMountItem; import com.facebook.react.fabric.mounting.mountitems.DispatchIntCommandMountItem; import com.facebook.react.fabric.mounting.mountitems.DispatchStringCommandMountItem; @@ -61,7 +66,12 @@ public UIManager get() { Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "FabricJSIModuleProvider.registerBinding"); final Binding binding = new Binding(); // TODO T31905686: remove this call - loadClasses(); + if (ReactFeatureFlags.eagerInitializeFabricClasses) { + loadClasses(); + } + if (ReactFeatureFlags.enableEagerInitializeMapBufferSoFile) { + ReadableMapBufferSoLoader.staticInit(); + } MessageQueueThread jsMessageQueueThread = mReactApplicationContext .getCatalystInstance() @@ -112,21 +122,27 @@ private static void loadClasses() { DispatchCommandMountItem.class.getClass(); DispatchIntCommandMountItem.class.getClass(); DispatchStringCommandMountItem.class.getClass(); + IntBufferBatchMountItem.class.getClass(); MountItem.class.getClass(); PreAllocateViewMountItem.class.getClass(); SendAccessibilityEvent.class.getClass(); LayoutMetricsConversions.class.getClass(); MountingManager.class.getClass(); + MountItemDispatcher.class.getClass(); + SurfaceMountingManager.class.getClass(); Binding.class.getClass(); ComponentFactory.class.getClass(); + CoreComponentsRegistry.class.getClass(); FabricComponents.class.getClass(); FabricSoLoader.class.getClass(); FabricUIManager.class.getClass(); GuardedFrameCallback.class.getClass(); StateWrapper.class.getClass(); StateWrapperImpl.class.getClass(); + SurfaceHandler.class.getClass(); + SurfaceHandlerBinding.class.getClass(); BatchEventDispatchedListener.class.getClass(); ReactNativeConfig.class.getClass(); - IntBufferBatchMountItem.class.getClass(); + ReadableMapBuffer.class.getClass(); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index aa01b18d593476..69ce09fb4a0ae7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -42,7 +42,6 @@ import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactMarker; import com.facebook.react.bridge.ReactMarkerConstants; -import com.facebook.react.bridge.ReactNoCrashSoftException; import com.facebook.react.bridge.ReactSoftException; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; @@ -79,6 +78,7 @@ import com.facebook.react.uimanager.ViewManagerRegistry; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.EventDispatcherImpl; +import com.facebook.react.uimanager.events.LockFreeEventDispatcherImpl; import com.facebook.react.views.text.TextLayoutManager; import com.facebook.react.views.text.TextLayoutManagerMapBuffer; import java.util.HashMap; @@ -172,7 +172,10 @@ public FabricUIManager( mMountingManager = new MountingManager(viewManagerRegistry); mMountItemDispatcher = new MountItemDispatcher(mMountingManager, new MountItemDispatchListener()); - mEventDispatcher = new EventDispatcherImpl(reactContext); + mEventDispatcher = + ReactFeatureFlags.enableLockFreeEventDispatcher + ? new LockFreeEventDispatcherImpl(reactContext) + : new EventDispatcherImpl(reactContext); mShouldDeallocateEventDispatcher = true; mEventBeatManager = eventBeatManager; mReactApplicationContext.addLifecycleEventListener(this); @@ -574,11 +577,12 @@ public void execute(@NonNull MountingManager mountingManager) { try { mountingManager.updateProps(reactTag, props); } catch (Exception ex) { - // TODO T42943890: Fix animations in Fabric and remove this try/catch - ReactSoftException.logSoftException( - TAG, - new ReactNoCrashSoftException( - "Caught exception in synchronouslyUpdateViewOnUIThread", ex)); + // TODO T42943890: Fix animations in Fabric and remove this try/catch? + // There might always be race conditions between surface teardown and + // animations/other operations, so it may not be feasible to remove this. + // Practically 100% of reported errors from this point are because the + // surface has stopped by this point, but the MountItem was queued before + // the surface was stopped. It's likely not feasible to prevent all such races. } } @@ -775,6 +779,30 @@ public void receiveEvent(int reactTag, String eventName, @Nullable WritableMap p @Override public void receiveEvent( int surfaceId, int reactTag, String eventName, @Nullable WritableMap params) { + receiveEvent(surfaceId, reactTag, eventName, false, 0, params); + } + + /** + * receiveEvent API that emits an event to C++. If `canCoalesceEvent` is true, that signals that + * C++ may coalesce the event optionally. Otherwise, coalescing can happen in Java before + * emitting. + * + *

`customCoalesceKey` is currently unused. + * + * @param surfaceId + * @param reactTag + * @param eventName + * @param canCoalesceEvent + * @param customCoalesceKey + * @param params + */ + public void receiveEvent( + int surfaceId, + int reactTag, + String eventName, + boolean canCoalesceEvent, + int customCoalesceKey, + @Nullable WritableMap params) { if (ReactBuildConfig.DEBUG && surfaceId == View.NO_ID) { FLog.d(TAG, "Emitted event without surfaceId: [%d] %s", reactTag, eventName); } @@ -787,7 +815,11 @@ public void receiveEvent( return; } - eventEmitter.invoke(eventName, params); + if (canCoalesceEvent) { + eventEmitter.invoke(eventName, params); + } else { + eventEmitter.invokeUnique(eventName, params, customCoalesceKey); + } } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java index a1cd86518c40e0..35c2b533586f05 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java @@ -38,6 +38,9 @@ private EventEmitterWrapper() { private native void invokeEvent(@NonNull String eventName, @NonNull NativeMap params); + private native void invokeUniqueEvent( + @NonNull String eventName, @NonNull NativeMap params, int customCoalesceKey); + /** * Invokes the execution of the C++ EventEmitter. * @@ -48,4 +51,17 @@ public void invoke(@NonNull String eventName, @Nullable WritableMap params) { NativeMap payload = params == null ? new WritableNativeMap() : (NativeMap) params; invokeEvent(eventName, payload); } + + /** + * Invokes the execution of the C++ EventEmitter. C++ will coalesce events sent to the same + * target. + * + * @param eventName {@link String} name of the event to execute. + * @param params {@link WritableMap} payload of the event + */ + public void invokeUnique( + @NonNull String eventName, @Nullable WritableMap params, int customCoalesceKey) { + NativeMap payload = params == null ? new WritableNativeMap() : (NativeMap) params; + invokeUniqueEvent(eventName, payload, customCoalesceKey); + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java index f0856af612e9a8..82d209ab494f40 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java @@ -47,10 +47,22 @@ public void receiveEvent(int reactTag, @NonNull String eventName, @Nullable Writ @Override public void receiveEvent( int surfaceId, int reactTag, String eventName, @Nullable WritableMap params) { + receiveEvent(surfaceId, reactTag, eventName, false, 0, params); + } + + @Override + public void receiveEvent( + int surfaceId, + int reactTag, + String eventName, + boolean canCoalesceEvent, + int customCoalesceKey, + @Nullable WritableMap params) { Systrace.beginSection( Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "FabricEventEmitter.receiveEvent('" + eventName + "')"); - mUIManager.receiveEvent(surfaceId, reactTag, eventName, params); + mUIManager.receiveEvent( + surfaceId, reactTag, eventName, canCoalesceEvent, customCoalesceKey, params); Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); } @@ -85,7 +97,7 @@ public void receiveTouches( rootNodeID = targetReactTag; } - receiveEvent(targetSurfaceId, rootNodeID, eventTopLevelType, touch); + receiveEvent(targetSurfaceId, rootNodeID, eventTopLevelType, false, 0, touch); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk index 528235e8f3ebe3..64c8f3c532f12a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk @@ -11,7 +11,7 @@ LOCAL_MODULE := fabricjni LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) -LOCAL_SHARED_LIBRARIES := libreactconfig librrc_slider librrc_progressbar librrc_switch librrc_modal libyoga libglog libfb libfbjni libglog_init libfolly_json libfolly_futures libreact_render_mounting libreactnativeutilsjni libreact_utils libreact_render_debug libreact_render_graphics libreact_render_core react_render_componentregistry librrc_view librrc_unimplementedview librrc_root librrc_scrollview libbetter libreact_render_attributedstring libreact_render_uimanager libreact_render_templateprocessor libreact_render_scheduler libreact_render_animations libreact_render_imagemanager libreact_render_textlayoutmanager libreact_codegen_rncore rrc_text librrc_image librrc_textinput librrc_picker libreact_debug libreact_render_mapbuffer libmapbufferjni libreact_render_telemetry +LOCAL_SHARED_LIBRARIES := libreactconfig librrc_slider librrc_progressbar librrc_switch librrc_modal libyoga libglog libfb libfbjni libglog_init libfolly_json libfolly_futures libreact_render_mounting libreactnativeutilsjni libreact_utils libreact_render_debug libreact_render_graphics libreact_render_core react_render_componentregistry librrc_view librrc_unimplementedview librrc_root librrc_scrollview libbetter libreact_render_attributedstring libreact_render_uimanager libreact_render_templateprocessor libreact_render_scheduler libreact_render_animations libreact_render_imagemanager libreact_render_textlayoutmanager libreact_codegen_rncore rrc_text librrc_image librrc_textinput librrc_picker libreact_debug libreact_render_mapbuffer libmapbufferjni libreact_render_telemetry libreact_render_runtimescheduler LOCAL_STATIC_LIBRARIES := @@ -57,6 +57,7 @@ $(call import-module,react/renderer/graphics) $(call import-module,react/renderer/imagemanager) $(call import-module,react/renderer/mapbuffer) $(call import-module,react/renderer/mounting) +$(call import-module,react/renderer/runtimescheduler) $(call import-module,react/renderer/scheduler) $(call import-module,react/renderer/templateprocessor) $(call import-module,react/renderer/textlayoutmanager) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/AsyncEventBeatV2.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/AsyncEventBeatV2.cpp new file mode 100644 index 00000000000000..1d9b2dd27f2f60 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/AsyncEventBeatV2.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include + +#include "AsyncEventBeatV2.h" + +namespace facebook::react { + +AsyncEventBeatV2::AsyncEventBeatV2( + EventBeat::SharedOwnerBox const &ownerBox, + EventBeatManager *eventBeatManager, + RuntimeExecutor runtimeExecutor, + jni::global_ref javaUIManager) + : EventBeat(ownerBox), + eventBeatManager_(eventBeatManager), + runtimeExecutor_(runtimeExecutor), + javaUIManager_(javaUIManager) { + eventBeatManager->addObserver(*this); +} + +AsyncEventBeatV2::~AsyncEventBeatV2() { + eventBeatManager_->removeObserver(*this); +} + +void AsyncEventBeatV2::tick() const { + if (!isRequested_ || isBeatCallbackScheduled_) { + return; + } + + isRequested_ = false; + isBeatCallbackScheduled_ = true; + + runtimeExecutor_([this, ownerBox = ownerBox_](jsi::Runtime &runtime) { + isBeatCallbackScheduled_ = false; + auto owner = ownerBox->owner.lock(); + if (!owner) { + return; + } + + if (beatCallback_) { + beatCallback_(runtime); + } + }); +} + +void AsyncEventBeatV2::induce() const { + tick(); +} + +void AsyncEventBeatV2::request() const { + bool alreadyRequested = isRequested_; + EventBeat::request(); + if (!alreadyRequested) { + // Notifies java side that an event will be dispatched (e.g. LayoutEvent) + static auto onRequestEventBeat = + jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") + ->getMethod("onRequestEventBeat"); + onRequestEventBeat(javaUIManager_); + } +} + +} // namespace facebook::react diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/AsyncEventBeatV2.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/AsyncEventBeatV2.h new file mode 100644 index 00000000000000..acd682f4cd856b --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/AsyncEventBeatV2.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include "EventBeatManager.h" + +namespace facebook::react { + +class AsyncEventBeatV2 final : public EventBeat, + public EventBeatManagerObserver { + public: + AsyncEventBeatV2( + EventBeat::SharedOwnerBox const &ownerBox, + EventBeatManager *eventBeatManager, + RuntimeExecutor runtimeExecutor, + jni::global_ref javaUIManager); + + ~AsyncEventBeatV2() override; + + void tick() const override; + + void induce() const override; + + void request() const override; + + private: + EventBeatManager *eventBeatManager_; + RuntimeExecutor runtimeExecutor_; + jni::global_ref javaUIManager_; + mutable std::atomic isBeatCallbackScheduled_{false}; +}; + +} // namespace facebook::react diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK index 26a8474dd0c46d..16da889ff11e01 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK @@ -34,6 +34,7 @@ rn_xplat_cxx_library( react_native_xplat_target("react/renderer/scheduler:scheduler"), react_native_xplat_target("react/renderer/componentregistry:componentregistry"), react_native_xplat_target("react/renderer/components/scrollview:scrollview"), + react_native_xplat_target("react/renderer/runtimescheduler:runtimescheduler"), react_native_xplat_target("runtimeexecutor:runtimeexecutor"), react_native_target("jni/react/jni:jni"), "//xplat/fbsystrace:fbsystrace", diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp index 192f8493f9485b..a141f5343e92e8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp @@ -7,6 +7,7 @@ #include "Binding.h" #include "AsyncEventBeat.h" +#include "AsyncEventBeatV2.h" #include "EventEmitterWrapper.h" #include "ReactNativeConfigHolder.h" #include "StateWrapperImpl.h" @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -452,6 +454,17 @@ void Binding::setConstraints( } } +bool isMapBufferSerializationEnabled() { + static const auto reactFeatureFlagsJavaDescriptor = + jni::findClassStatic(Binding::ReactFeatureFlagsJavaDescriptor); + static const auto isMapBufferSerializationEnabledMethod = + reactFeatureFlagsJavaDescriptor->getStaticMethod( + "isMapBufferSerializationEnabled"); + bool value = + isMapBufferSerializationEnabledMethod(reactFeatureFlagsJavaDescriptor); + return value; +} + void Binding::installFabricUIManager( jni::alias_ref runtimeExecutorHolder, jni::alias_ref javaUIManager, @@ -487,22 +500,53 @@ void Binding::installFabricUIManager( auto sharedJSMessageQueueThread = std::make_shared(jsMessageQueueThread); auto runtimeExecutor = runtimeExecutorHolder->cthis()->get(); + std::shared_ptr runtimeScheduler; + + if (config->getBool("react_fabric:enable_runtimescheduler_android")) { + runtimeScheduler = std::make_shared(runtimeExecutor); + + auto originalRuntimeExecutor = runtimeExecutorHolder->cthis()->get(); + runtimeExecutor = + [originalRuntimeExecutor, runtimeScheduler]( + std::function &&callback) { + runtimeScheduler->scheduleWork(std::move(callback)); + }; + } + + auto enableV2AsynchronousEventBeat = + config->getBool("react_fabric:enable_asynchronous_event_beat_v2_android"); // TODO: T31905686 Create synchronous Event Beat jni::global_ref localJavaUIManager = javaUIManager_; EventBeat::Factory synchronousBeatFactory = - [eventBeatManager, runtimeExecutor, localJavaUIManager]( - EventBeat::SharedOwnerBox const &ownerBox) { - return std::make_unique( - ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); - }; + [eventBeatManager, + runtimeExecutor, + localJavaUIManager, + enableV2AsynchronousEventBeat](EventBeat::SharedOwnerBox const &ownerBox) + -> std::unique_ptr { + if (enableV2AsynchronousEventBeat) { + return std::make_unique( + ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); + } else { + return std::make_unique( + ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); + } + }; EventBeat::Factory asynchronousBeatFactory = - [eventBeatManager, runtimeExecutor, localJavaUIManager]( - EventBeat::SharedOwnerBox const &ownerBox) { - return std::make_unique( - ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); - }; + [eventBeatManager, + runtimeExecutor, + localJavaUIManager, + enableV2AsynchronousEventBeat](EventBeat::SharedOwnerBox const &ownerBox) + -> std::unique_ptr { + if (enableV2AsynchronousEventBeat) { + return std::make_unique( + ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); + } else { + return std::make_unique( + ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); + } + }; contextContainer->insert("ReactNativeConfig", config); contextContainer->insert("FabricUIManager", javaUIManager_); @@ -511,9 +555,7 @@ void Binding::installFabricUIManager( reactNativeConfig_ = config; contextContainer->insert( - "MapBufferSerializationEnabled", - reactNativeConfig_->getBool( - "react_fabric:enable_mapbuffer_serialization_android")); + "MapBufferSerializationEnabled", isMapBufferSerializationEnabled()); disablePreallocateViews_ = reactNativeConfig_->getBool( "react_fabric:disabled_view_preallocation_android"); @@ -522,6 +564,7 @@ void Binding::installFabricUIManager( toolbox.contextContainer = contextContainer; toolbox.componentRegistryFactory = componentsRegistry->buildRegistryFunction; toolbox.runtimeExecutor = runtimeExecutor; + toolbox.runtimeScheduler = runtimeScheduler; toolbox.synchronousEventBeatFactory = synchronousBeatFactory; toolbox.asynchronousEventBeatFactory = asynchronousBeatFactory; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h index b16bd9dc63655e..df0aeeb45aa135 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.h @@ -76,6 +76,9 @@ class Binding : public jni::HybridClass, constexpr static auto UIManagerJavaDescriptor = "com/facebook/react/fabric/FabricUIManager"; + constexpr static auto ReactFeatureFlagsJavaDescriptor = + "com/facebook/react/config/ReactFeatureFlags"; + static void registerNatives(); private: diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp index 19fe921a46b807..afb73f9927a96a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.cpp @@ -25,10 +25,20 @@ void EventEmitterWrapper::invokeEvent( eventName, payload->consume(), EventPriority::AsynchronousBatched); } +void EventEmitterWrapper::invokeUniqueEvent( + std::string eventName, + NativeMap *payload, + int customCoalesceKey) { + // TODO: customCoalesceKey currently unused + eventEmitter->dispatchUniqueEvent(eventName, payload->consume()); +} + void EventEmitterWrapper::registerNatives() { registerHybrid({ makeNativeMethod("initHybrid", EventEmitterWrapper::initHybrid), makeNativeMethod("invokeEvent", EventEmitterWrapper::invokeEvent), + makeNativeMethod( + "invokeUniqueEvent", EventEmitterWrapper::invokeUniqueEvent), }); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h index dcc84ea6320e16..bfcc6059758293 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventEmitterWrapper.h @@ -26,6 +26,10 @@ class EventEmitterWrapper : public jni::HybridClass { SharedEventEmitter eventEmitter; void invokeEvent(std::string eventName, NativeMap *params); + void invokeUniqueEvent( + std::string eventName, + NativeMap *params, + int customCoalesceKey); private: static jni::local_ref initHybrid(jni::alias_ref); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java index 5aa1c5788fd247..2155755f451ab4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountItemDispatcher.java @@ -282,12 +282,17 @@ public void dispatchPreMountItems(long frameTimeNanos) { } PreAllocateViewMountItem preMountItemToDispatch = mPreMountItems.poll(); - // If list is empty, `poll` will return null, or var will never be set if (preMountItemToDispatch == null) { break; } + if (ENABLE_FABRIC_LOGS) { + printMountItem( + preMountItemToDispatch, + "dispatchPreMountItems: Dispatching PreAllocateViewMountItem"); + } + executeOrEnqueue(preMountItemToDispatch); } } finally { @@ -299,6 +304,12 @@ public void dispatchPreMountItems(long frameTimeNanos) { private void executeOrEnqueue(MountItem item) { if (mMountingManager.isWaitingForViewAttach(item.getSurfaceId())) { + if (ENABLE_FABRIC_LOGS) { + FLog.e( + TAG, + "executeOrEnqueue: Item execution delayed, surface %s is not ready yet", + item.getSurfaceId()); + } SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(item.getSurfaceId()); surfaceMountingManager.executeOnViewAttach(item); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java index 5313e1a9154e44..97a8822d94937a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java @@ -263,13 +263,15 @@ public void receiveCommand( * Send an accessibility eventType to a Native View. eventType is any valid `AccessibilityEvent.X` * value. * - *

Why accept `-1` SurfaceId? Currently there are calls to - * UIManagerModule.sendAccessibilityEvent which is a legacy API and accepts only reactTag. We will - * have to investigate and migrate away from those calls over time. + *

Why accept `-1` SurfaceId? Currently there are calls to UIManager.sendAccessibilityEvent + * which is a legacy API and accepts only reactTag. We will have to investigate and migrate away + * from those calls over time. * - * @param surfaceId - * @param reactTag - * @param eventType + * @param surfaceId {@link int} that identifies the surface or -1 to temporarily support backward + * compatibility. + * @param reactTag {@link int} that identifies the react Tag of the view. + * @param eventType {@link int} that identifies Android eventType. see {@link + * View#sendAccessibilityEvent} */ public void sendAccessibilityEvent(int surfaceId, int reactTag, int eventType) { UiThreadUtil.assertOnUiThread(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java index 6002cff9ef618f..e61f26a2dd66f0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java @@ -257,6 +257,11 @@ public void stopSurface() { new Runnable() { @Override public void run() { + // We must call `onDropViewInstance` on all remaining Views + for (ViewState viewState : mTagToViewState.values()) { + onViewStateDeleted(viewState); + } + // Evict all views from cache and memory mLastSuccessfulQueryTime = System.currentTimeMillis(); mTagSetForStoppedSurface = mTagToViewState.keySet(); @@ -794,6 +799,21 @@ public synchronized void setJSResponder( mJSResponderHandler.setJSResponder(initialReactTag, view.getParent()); } + @UiThread + private void onViewStateDeleted(ViewState viewState) { + // Destroy state immediately instead of waiting for Java GC. + if (viewState.mStateWrapper != null) { + viewState.mStateWrapper.destroyState(); + viewState.mStateWrapper = null; + } + + // For non-root views we notify viewmanager with {@link ViewManager#onDropInstance} + ViewManager viewManager = viewState.mViewManager; + if (!viewState.mIsRoot && viewManager != null) { + viewManager.onDropViewInstance(viewState.mView); + } + } + @UiThread public void deleteView(int reactTag) { UiThreadUtil.assertOnUiThread(); @@ -816,17 +836,7 @@ public void deleteView(int reactTag) { // or StopSurface being called, so we do not handle deleting descendents of the View. mTagToViewState.remove(reactTag); - // Destroy state immediately instead of waiting for Java GC. - if (viewState.mStateWrapper != null) { - viewState.mStateWrapper.destroyState(); - viewState.mStateWrapper = null; - } - - // For non-root views we notify viewmanager with {@link ViewManager#onDropInstance} - ViewManager viewManager = viewState.mViewManager; - if (!viewState.mIsRoot && viewManager != null) { - viewManager.onDropViewInstance(viewState.mView); - } + onViewStateDeleted(viewState); } @UiThread diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java index d6d3a0f9c2b4e5..9d2aa1d63c8b93 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java @@ -193,7 +193,7 @@ public boolean shouldSchedule() { public String toString() { try { StringBuilder s = new StringBuilder(); - s.append("IntBufferBatchMountItem:"); + s.append(String.format("IntBufferBatchMountItem [surface:%d]:\n", mSurfaceId)); int i = 0, j = 0; while (i < mIntBufferLen) { int rawType = mIntBuffer[i++]; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java index 7b540ae89a42d3..4516d60dd8571d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java @@ -7,7 +7,6 @@ package com.facebook.react.fabric.mounting.mountitems; -import static com.facebook.react.fabric.FabricUIManager.ENABLE_FABRIC_LOGS; import static com.facebook.react.fabric.FabricUIManager.IS_DEVELOPMENT_ENVIRONMENT; import static com.facebook.react.fabric.FabricUIManager.TAG; @@ -51,9 +50,6 @@ public int getSurfaceId() { @Override public void execute(@NonNull MountingManager mountingManager) { - if (ENABLE_FABRIC_LOGS) { - FLog.d(TAG, "Executing pre-allocation of: " + toString()); - } SurfaceMountingManager surfaceMountingManager = mountingManager.getSurfaceManager(mSurfaceId); if (surfaceMountingManager == null) { FLog.e( diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java index 429fca866448ca..e6971464889241 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java @@ -101,7 +101,7 @@ public void onDismiss(DialogInterface dialog) { * If the action is dismiss, year, month and date are undefined. */ @Override - public void open(@Nullable final ReadableMap options, Promise promise) { + public void open(@Nullable final ReadableMap options, final Promise promise) { Activity raw_activity = getCurrentActivity(); if (raw_activity == null || !(raw_activity instanceof FragmentActivity)) { promise.reject( @@ -112,20 +112,26 @@ public void open(@Nullable final ReadableMap options, Promise promise) { FragmentActivity activity = (FragmentActivity) raw_activity; - FragmentManager fragmentManager = activity.getSupportFragmentManager(); + final FragmentManager fragmentManager = activity.getSupportFragmentManager(); DialogFragment oldFragment = (DialogFragment) fragmentManager.findFragmentByTag(FRAGMENT_TAG); if (oldFragment != null) { oldFragment.dismiss(); } - DatePickerDialogFragment fragment = new DatePickerDialogFragment(); - if (options != null) { - final Bundle args = createFragmentArguments(options); - fragment.setArguments(args); - } - final DatePickerDialogListener listener = new DatePickerDialogListener(promise); - fragment.setOnDismissListener(listener); - fragment.setOnDateSetListener(listener); - fragment.show(fragmentManager, FRAGMENT_TAG); + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + DatePickerDialogFragment fragment = new DatePickerDialogFragment(); + if (options != null) { + final Bundle args = createFragmentArguments(options); + fragment.setArguments(args); + } + final DatePickerDialogListener listener = new DatePickerDialogListener(promise); + fragment.setOnDismissListener(listener); + fragment.setOnDateSetListener(listener); + fragment.show(fragmentManager, FRAGMENT_TAG); + } + }); } private Bundle createFragmentArguments(ReadableMap options) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java index db0224d0871cda..b50f3dafb485a3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSTouchDispatcher.java @@ -12,6 +12,7 @@ import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; import com.facebook.react.common.ReactConstants; +import com.facebook.react.uimanager.common.UIManagerType; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.TouchEvent; import com.facebook.react.uimanager.events.TouchEventCoalescingKeyHelper; @@ -50,14 +51,22 @@ public void onChildStartedNativeGesture( mTargetTag = -1; } + /** + * See Event.java. By contract, this surfaceId should be a valid SurfaceId in Fabric, and should + * ALWAYS return -1 in non-Fabric. + * + * @return + */ private int getSurfaceId() { - if (mRootViewGroup instanceof ReactRoot) { + if (mRootViewGroup != null + && mRootViewGroup instanceof ReactRoot + && ((ReactRoot) mRootViewGroup).getUIManagerType() == UIManagerType.FABRIC) { + if (mRootViewGroup.getContext() instanceof ThemedReactContext) { + ThemedReactContext context = (ThemedReactContext) mRootViewGroup.getContext(); + return context.getSurfaceId(); + } return ((ReactRoot) mRootViewGroup).getRootViewTag(); } - if (mRootViewGroup != null && mRootViewGroup.getContext() instanceof ThemedReactContext) { - ThemedReactContext context = (ThemedReactContext) mRootViewGroup.getContext(); - return context.getSurfaceId(); - } return -1; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index e429eba16a8dcd..5ca18f60b0579c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -30,7 +30,6 @@ import com.facebook.react.bridge.SoftAssertions; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.common.build.ReactBuildConfig; -import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.touch.JSResponderHandler; import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController; import com.facebook.react.uimanager.layoutanimation.LayoutAnimationListener; @@ -852,9 +851,8 @@ public synchronized void dispatchCommand( + commandId); } ViewManager viewManager = resolveViewManager(reactTag); - ViewManagerDelegate delegate; - if (ReactFeatureFlags.useViewManagerDelegatesForCommands - && (delegate = viewManager.getDelegate()) != null) { + ViewManagerDelegate delegate = viewManager.getDelegate(); + if (delegate != null) { delegate.receiveCommand(view, commandId, args); } else { viewManager.receiveCommand(view, commandId, args); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java index 3e196698f24e9d..66e1cb38f3a924 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java @@ -13,7 +13,6 @@ import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMapKeySetIterator; -import com.facebook.react.config.ReactFeatureFlags; /** * Class responsible for optimizing the native view hierarchy while still respecting the final UI @@ -425,18 +424,16 @@ private void transitionLayoutOnlyViewToNativeView( // Bit of a hack: we need to update the layout of this node's children now that it's no longer // layout-only, but we may still receive more layout updates at the end of this batch that we // don't want to ignore. - if (ReactFeatureFlags.enableTransitionLayoutOnlyViewCleanup) { - FLog.i( - TAG, - "Transitioning LayoutOnlyView - tag: " - + node.getReactTag() - + " - rootTag: " - + node.getRootTag() - + " - hasProps: " - + (props != null) - + " - tagsWithLayout.size: " - + mTagsWithLayoutVisited.size()); - } + FLog.i( + TAG, + "Transitioning LayoutOnlyView - tag: " + + node.getReactTag() + + " - rootTag: " + + node.getRootTag() + + " - hasProps: " + + (props != null) + + " - tagsWithLayout.size: " + + mTagsWithLayoutVisited.size()); Assertions.assertCondition(mTagsWithLayoutVisited.size() == 0); applyLayoutBase(node); for (int i = 0; i < node.getChildCount(); i++) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java index afbe05610b0ff8..b87e976ef62437 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java @@ -82,6 +82,7 @@ private void scheduleAccessibilityEventSender(View host) { public enum AccessibilityRole { NONE, BUTTON, + TOGGLEBUTTON, LINK, SEARCH, IMAGE, @@ -112,6 +113,8 @@ public static String getValue(AccessibilityRole role) { switch (role) { case BUTTON: return "android.widget.Button"; + case TOGGLEBUTTON: + return "android.widget.ToggleButton"; case SEARCH: return "android.widget.EditText"; case IMAGE: @@ -392,6 +395,10 @@ public static void setRole( } else if (role.equals(AccessibilityRole.BUTTON)) { nodeInfo.setRoleDescription(context.getString(R.string.button_description)); nodeInfo.setClickable(true); + } else if (role.equals(AccessibilityRole.TOGGLEBUTTON)) { + nodeInfo.setRoleDescription(context.getString(R.string.toggle_button_description)); + nodeInfo.setClickable(true); + nodeInfo.setCheckable(true); } else if (role.equals(AccessibilityRole.SUMMARY)) { nodeInfo.setRoleDescription(context.getString(R.string.summary_description)); } else if (role.equals(AccessibilityRole.HEADER)) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroupHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroupHelper.java index 393b7cc602b040..8c9399073af3dd 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroupHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactClippingViewGroupHelper.java @@ -43,12 +43,16 @@ public static void calculateClippingRect(View view, Rect outputRect) { // Intersect the view with the parent's rectangle // This will result in the overlap with coordinates in the parent space if (!sHelperRect.intersect( - view.getLeft(), view.getTop(), view.getRight(), view.getBottom())) { + view.getLeft(), + view.getTop() + (int) view.getTranslationY(), + view.getRight(), + view.getBottom() + (int) view.getTranslationY())) { outputRect.setEmpty(); return; } // Now we move the coordinates to the View's coordinate space sHelperRect.offset(-view.getLeft(), -view.getTop()); + sHelperRect.offset(-(int) view.getTranslationX(), -(int) view.getTranslationY()); sHelperRect.offset(view.getScrollX(), view.getScrollY()); outputRect.set(sHelperRect); return; diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java index ae025211f7a08f..bce8995feeedf4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java @@ -21,7 +21,6 @@ import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.WritableArray; import com.facebook.react.common.ReactConstants; -import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener; import com.facebook.react.uimanager.events.EventDispatcher; @@ -965,9 +964,7 @@ protected void applyUpdatesRecursive(ReactShadowNode cssNode, float absoluteX, f } } cssNode.markUpdateSeen(); - if (ReactFeatureFlags.enableTransitionLayoutOnlyViewCleanup) { - mNativeViewHierarchyOptimizer.onViewUpdatesCompleted(cssNode); - } + mNativeViewHierarchyOptimizer.onViewUpdatesCompleted(cssNode); } public void addUIBlock(UIBlock block) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java index b2b82aca343f29..4419106085a28d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerHelper.java @@ -29,6 +29,7 @@ /** Helper class for {@link UIManager}. */ public class UIManagerHelper { + private static final String TAG = UIManagerHelper.class.getName(); public static final int PADDING_START_INDEX = 0; public static final int PADDING_END_INDEX = 1; public static final int PADDING_TOP_INDEX = 2; @@ -55,7 +56,7 @@ private static UIManager getUIManager( @Nullable UIManager uiManager = (UIManager) context.getJSIModule(JSIModuleType.UIManager); if (uiManager == null) { ReactSoftException.logSoftException( - "UIManagerHelper", + TAG, new ReactNoCrashSoftException( "Cannot get UIManager because the instance hasn't been initialized yet.")); return null; @@ -65,7 +66,7 @@ private static UIManager getUIManager( if (!context.hasCatalystInstance()) { ReactSoftException.logSoftException( - "UIManagerHelper", + TAG, new ReactNoCrashSoftException( "Cannot get UIManager because the context doesn't contain a CatalystInstance.")); return null; @@ -74,7 +75,7 @@ private static UIManager getUIManager( // down. if (!context.hasActiveReactInstance()) { ReactSoftException.logSoftException( - "UIManagerHelper", + TAG, new ReactNoCrashSoftException( "Cannot get UIManager because the context doesn't contain an active CatalystInstance.")); if (returnNullIfCatalystIsInactive) { @@ -82,9 +83,18 @@ private static UIManager getUIManager( } } CatalystInstance catalystInstance = context.getCatalystInstance(); - return uiManagerType == FABRIC - ? (UIManager) catalystInstance.getJSIModule(JSIModuleType.UIManager) - : catalystInstance.getNativeModule(UIManagerModule.class); + try { + return uiManagerType == FABRIC + ? (UIManager) catalystInstance.getJSIModule(JSIModuleType.UIManager) + : catalystInstance.getNativeModule(UIManagerModule.class); + } catch (IllegalArgumentException ex) { + // TODO T67518514 Clean this up once we migrate everything over to bridgeless mode + ReactSoftException.logSoftException( + TAG, + new ReactNoCrashSoftException( + "Cannot get UIManager for UIManagerType: " + uiManagerType)); + return catalystInstance.getNativeModule(UIManagerModule.class); + } } /** @@ -96,8 +106,7 @@ public static EventDispatcher getEventDispatcherForReactTag(ReactContext context EventDispatcher eventDispatcher = getEventDispatcher(context, getUIManagerType(reactTag)); if (eventDispatcher == null) { ReactSoftException.logSoftException( - "UIManagerHelper", - new IllegalStateException("Cannot get EventDispatcher for reactTag " + reactTag)); + TAG, new IllegalStateException("Cannot get EventDispatcher for reactTag " + reactTag)); } return eventDispatcher; } @@ -119,7 +128,7 @@ public static EventDispatcher getEventDispatcher( UIManager uiManager = getUIManager(context, uiManagerType, false); if (uiManager == null) { ReactSoftException.logSoftException( - "UIManagerHelper", + TAG, new ReactNoCrashSoftException( "Unable to find UIManager for UIManagerType " + uiManagerType)); return null; @@ -127,7 +136,7 @@ public static EventDispatcher getEventDispatcher( EventDispatcher eventDispatcher = (EventDispatcher) uiManager.getEventDispatcher(); if (eventDispatcher == null) { ReactSoftException.logSoftException( - "UIManagerHelper", + TAG, new IllegalStateException( "Cannot get EventDispatcher for UIManagerType " + uiManagerType)); } @@ -172,7 +181,7 @@ public static int getSurfaceId(View view) { // All Fabric-managed Views (should) have a ThemedReactContext attached. if (surfaceId == -1) { ReactSoftException.logSoftException( - "UIManagerHelper", + TAG, new IllegalStateException( "Fabric View [" + reactTag + "] does not have SurfaceId associated with it")); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java index ccde14ae9c21ed..6af66a6f080174 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java @@ -15,7 +15,6 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.touch.JSResponderHandler; import com.facebook.react.touch.ReactInterceptingViewGroup; import com.facebook.react.uimanager.annotations.ReactProp; @@ -41,8 +40,8 @@ public abstract class ViewManager * @param props */ public void updateProperties(@NonNull T viewToUpdate, ReactStylesDiffMap props) { - final ViewManagerDelegate delegate; - if (ReactFeatureFlags.useViewManagerDelegates && (delegate = getDelegate()) != null) { + final ViewManagerDelegate delegate = getDelegate(); + if (delegate != null) { ViewManagerPropertyUpdater.updateProps(delegate, viewToUpdate, props); } else { ViewManagerPropertyUpdater.updateProps(this, viewToUpdate, props); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java index e8976cce961970..a93c0a82d88c06 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java @@ -11,6 +11,7 @@ import com.facebook.react.bridge.WritableMap; import com.facebook.react.common.SystemClock; import com.facebook.react.uimanager.IllegalViewOperationException; +import com.facebook.react.uimanager.common.UIManagerType; /** * A UI event that can be dispatched to JS. @@ -33,6 +34,7 @@ public abstract class Event { private static int sUniqueID = 0; private boolean mInitialized; + private @UIManagerType int mUIManagerType; private int mSurfaceId; private int mViewTag; private long mTimestampMs; @@ -67,10 +69,23 @@ protected void init(int viewTag) { protected void init(int surfaceId, int viewTag) { mSurfaceId = surfaceId; mViewTag = viewTag; - mInitialized = true; + + // We infer UIManagerType. Even though it's not passed in explicitly, we have a + // contract that Fabric events *always* have a SurfaceId passed in, and non-Fabric events + // NEVER have a SurfaceId passed in (the default/placeholder of -1 is passed in instead). + // Why does this matter? + // Events can be sent to Views that are part of the View hierarchy *but not directly managed + // by React Native*. For example, embedded custom hierachies, Litho hierachies, etc. + // In those cases it's important to konw that the Event should be sent to the Fabric or + // non-Fabric UIManager, and we cannot use the ViewTag for inference since it's not controlled + // by RN and is essentially a random number. + // At some point it would be great to pass the SurfaceContext here instead. + mUIManagerType = (surfaceId == -1 ? UIManagerType.DEFAULT : UIManagerType.FABRIC); // This is a *relative* time. See `getUnixTimestampMs`. mTimestampMs = SystemClock.uptimeMillis(); + + mInitialized = true; } /** @return the view id for the view that generated this event */ @@ -142,6 +157,10 @@ public void onDispose() {} onDispose(); } + public final @UIManagerType int getUIManagerType() { + return mUIManagerType; + } + /** @return the name of this event as registered in JS */ public abstract String getEventName(); @@ -188,4 +207,27 @@ public void dispatchModern(RCTModernEventEmitter rctEventEmitter) { } dispatch(rctEventEmitter); } + + /** + * Dispatch this event to JS using a V2 version of dispatchModern. See all comments from + * `dispatchModern` - all still apply. This method additionally allows C++ to coalesce events + * (Fabric only). This will ONLY be called in an experimental path, and in Fabric only. + */ + @Deprecated + public void dispatchModernV2(RCTModernEventEmitter rctEventEmitter) { + if (getSurfaceId() != -1) { + WritableMap eventData = getEventData(); + if (eventData != null) { + rctEventEmitter.receiveEvent( + getSurfaceId(), + getViewTag(), + getEventName(), + canCoalesce(), + getCoalescingKey(), + getEventData()); + return; + } + } + dispatch(rctEventEmitter); + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/LockFreeEventDispatcherImpl.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/LockFreeEventDispatcherImpl.java new file mode 100644 index 00000000000000..3ff83f30800b73 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/LockFreeEventDispatcherImpl.java @@ -0,0 +1,236 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.uimanager.events; + +import com.facebook.common.logging.FLog; +import com.facebook.infer.annotation.Assertions; +import com.facebook.react.bridge.LifecycleEventListener; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.UiThreadUtil; +import com.facebook.react.common.build.ReactBuildConfig; +import com.facebook.react.modules.core.ChoreographerCompat; +import com.facebook.react.modules.core.ReactChoreographer; +import com.facebook.react.uimanager.common.UIManagerType; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Class responsible for dispatching UI events to JS. The main purpose of this class is to act as an + * intermediary between UI code generating events and JS, making sure we don't send more events than + * JS can process. + * + *

To use it, create a subclass of {@link Event} and call {@link #dispatchEvent(Event)} whenever + * there's a UI event to dispatch. + * + *

This class works by installing a Choreographer frame callback on the main thread. This + * callback then enqueues a runnable on the JS thread (if one is not already pending) that is + * responsible for actually dispatch events to JS. This implementation depends on the properties + * that 1) FrameCallbacks run after UI events have been processed in Choreographer.java 2) when we + * enqueue a runnable on the JS queue thread, it won't be called until after any previously enqueued + * JS jobs have finished processing + * + *

If JS is taking a long time processing events, then the UI events generated on the UI thread + * can be coalesced into fewer events so that when the runnable runs, we don't overload JS with a + * ton of events and make it get even farther behind. + * + *

Ideally, we don't need this and JS is fast enough to process all the events each frame, but + * bad things happen, including load on CPUs from the system, and we should handle this case well. + * + *

== Event Cookies == + * + *

An event cookie is made up of the event type id, view tag, and a custom coalescing key. Only + * Events that have the same cookie can be coalesced. + * + *

Event Cookie Composition: VIEW_TAG_MASK = 0x00000000ffffffff EVENT_TYPE_ID_MASK = + * 0x0000ffff00000000 COALESCING_KEY_MASK = 0xffff000000000000 + * + *

This is a copy of EventDispatcherImpl, meant only to remove locking and synchronization. + */ +public class LockFreeEventDispatcherImpl implements EventDispatcher, LifecycleEventListener { + + private final boolean DEBUG_MODE = true && ReactBuildConfig.DEBUG; + private final String TAG = LockFreeEventDispatcherImpl.class.getSimpleName(); + + private final ReactApplicationContext mReactContext; + private final CopyOnWriteArrayList mListeners = + new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList mPostEventDispatchListeners = + new CopyOnWriteArrayList<>(); + private final LockFreeEventDispatcherImpl.ScheduleDispatchFrameCallback mCurrentFrameCallback = + new LockFreeEventDispatcherImpl.ScheduleDispatchFrameCallback(); + + private volatile ReactEventEmitter mReactEventEmitter; + + public LockFreeEventDispatcherImpl(ReactApplicationContext reactContext) { + mReactContext = reactContext; + mReactContext.addLifecycleEventListener(this); + mReactEventEmitter = new ReactEventEmitter(mReactContext); + } + + /** Sends the given Event to C++, where it will be flushed to JS ASAP. */ + public void dispatchEvent(Event event) { + Assertions.assertCondition(event.isInitialized(), "Dispatched event hasn't been initialized"); + Assertions.assertNotNull(mReactEventEmitter); + + if (DEBUG_MODE) { + FLog.d(TAG, "dispatchEvent: " + event.toString()); + } + + for (EventDispatcherListener listener : mListeners) { + listener.onEventDispatch(event); + } + + event.dispatchModernV2(mReactEventEmitter); + event.dispose(); + } + + public void dispatchAllEvents() { + maybePostFrameCallbackFromNonUI(); + } + + private void maybePostFrameCallbackFromNonUI() { + if (mReactEventEmitter != null) { + // If the host activity is paused, the frame callback may not be currently + // posted. Ensure that it is so that this event gets delivered promptly. + mCurrentFrameCallback.maybePostFromNonUI(); + } else { + // No JS application has started yet, or resumed. This can happen when a ReactRootView is + // added to view hierarchy, but ReactContext creation has not completed yet. In this case, any + // touch event dispatch will hit this codepath, and we simply queue them so that they + // are dispatched once ReactContext creation completes and JS app is running. + } + } + + /** Add a listener to this EventDispatcher. */ + public void addListener(EventDispatcherListener listener) { + mListeners.add(listener); + } + + /** Remove a listener from this EventDispatcher. */ + public void removeListener(EventDispatcherListener listener) { + mListeners.remove(listener); + } + + public void addBatchEventDispatchedListener(BatchEventDispatchedListener listener) { + mPostEventDispatchListeners.add(listener); + } + + public void removeBatchEventDispatchedListener(BatchEventDispatchedListener listener) { + mPostEventDispatchListeners.remove(listener); + } + + @Override + public void onHostResume() { + maybePostFrameCallbackFromNonUI(); + } + + @Override + public void onHostPause() { + stopFrameCallback(); + } + + @Override + public void onHostDestroy() { + stopFrameCallback(); + } + + public void onCatalystInstanceDestroyed() { + UiThreadUtil.runOnUiThread( + new Runnable() { + @Override + public void run() { + stopFrameCallback(); + } + }); + } + + private void stopFrameCallback() { + UiThreadUtil.assertOnUiThread(); + mCurrentFrameCallback.stop(); + } + + public void registerEventEmitter(@UIManagerType int uiManagerType, RCTEventEmitter eventEmitter) { + mReactEventEmitter.register(uiManagerType, eventEmitter); + } + + public void registerEventEmitter( + @UIManagerType int uiManagerType, RCTModernEventEmitter eventEmitter) { + mReactEventEmitter.register(uiManagerType, eventEmitter); + } + + public void unregisterEventEmitter(@UIManagerType int uiManagerType) { + mReactEventEmitter.unregister(uiManagerType); + } + + private class ScheduleDispatchFrameCallback extends ChoreographerCompat.FrameCallback { + private volatile boolean mIsPosted = false; + private boolean mShouldStop = false; + + @Override + public void doFrame(long frameTimeNanos) { + UiThreadUtil.assertOnUiThread(); + + if (mShouldStop) { + mIsPosted = false; + } else { + post(); + } + + driveEventBeats(); + } + + public void stop() { + mShouldStop = true; + } + + public void maybePost() { + if (!mIsPosted) { + mIsPosted = true; + post(); + } + } + + private void post() { + ReactChoreographer.getInstance() + .postFrameCallback(ReactChoreographer.CallbackType.TIMERS_EVENTS, mCurrentFrameCallback); + } + + public void maybePostFromNonUI() { + if (mIsPosted) { + return; + } + + // We should only hit this slow path when we receive events while the host activity is paused. + if (mReactContext.isOnUiQueueThread()) { + maybePost(); + } else { + mReactContext.runOnUiQueueThread( + new Runnable() { + @Override + public void run() { + maybePost(); + } + }); + } + } + } + + /** + * Is this a misnomer? It's called "driveEventBeats" but then is just calls + * `onBatchEventDispatched` listeners? Practically, all that `onBatchEventDispatched` is used for + * in Fabric is to drive AsyncEventBeats. + * + *

If this class ships for Fabric, we should remove `driveEventBeats` from here entirely, + * because it no longer needs to be connected to this event dispatcher. We should/probably can + * also delete `onRequestEventBeat` entirely. + */ + private void driveEventBeats() { + for (BatchEventDispatchedListener listener : mPostEventDispatchListeners) { + listener.onBatchEventDispatched(); + } + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java index a05f2c83b7d69f..47fbd7641658d5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java @@ -21,4 +21,12 @@ */ public interface RCTModernEventEmitter extends RCTEventEmitter { void receiveEvent(int surfaceId, int targetTag, String eventName, @Nullable WritableMap event); + + void receiveEvent( + int surfaceId, + int targetTag, + String eventName, + boolean canCoalesceEvent, + int customCoalesceKey, + @Nullable WritableMap event); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java index 641b8459ec1329..45cfbfc258f406 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java @@ -59,6 +59,19 @@ public void receiveEvent(int targetReactTag, String eventName, @Nullable Writabl receiveEvent(-1, targetReactTag, eventName, event); } + @Override + public void receiveEvent( + int surfaceId, + int targetTag, + String eventName, + boolean canCoalesceEvent, + int customCoalesceKey, + @Nullable WritableMap event) { + // The two additional params here, `canCoalesceEvent` and `customCoalesceKey`, have no + // meaning outside of Fabric. + receiveEvent(surfaceId, targetTag, eventName, event); + } + @Override public void receiveTouches( String eventName, WritableArray touches, WritableArray changedIndices) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/interfaces/ViewProps.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/interfaces/ViewProps.java index dbc2650f14c400..2327b364980dae 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/interfaces/ViewProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/interfaces/ViewProps.java @@ -258,7 +258,9 @@ public static boolean isLayoutOnly(ReadableMap map, String prop) { // Ignore if explicitly set to default opacity. return map.isNull(OPACITY) || map.getDouble(OPACITY) == 1d; case BORDER_RADIUS: // Without a background color or border width set, a border won't show. - if (map.hasKey(BACKGROUND_COLOR) && map.getInt(BACKGROUND_COLOR) != Color.TRANSPARENT) { + if (map.hasKey(BACKGROUND_COLOR) + && !map.isNull(BACKGROUND_COLOR) + && map.getInt(BACKGROUND_COLOR) != Color.TRANSPARENT) { return false; } if (map.hasKey(BORDER_WIDTH) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerClosedEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerClosedEvent.java index 06be4490ab2b9f..29c724c1ada911 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerClosedEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerClosedEvent.java @@ -33,10 +33,4 @@ public String getEventName() { protected WritableMap getEventData() { return Arguments.createMap(); } - - @Override - public short getCoalescingKey() { - // All events for a given view can be coalesced. - return 0; - } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerOpenedEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerOpenedEvent.java index 35adbe6b71b403..d1402f593cecef 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerOpenedEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerOpenedEvent.java @@ -33,10 +33,4 @@ public String getEventName() { protected WritableMap getEventData() { return Arguments.createMap(); } - - @Override - public short getCoalescingKey() { - // All events for a given view can be coalesced. - return 0; - } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerSlideEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerSlideEvent.java index d8dda5c560a532..57f2ef5fa60ac1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerSlideEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerSlideEvent.java @@ -37,12 +37,6 @@ public String getEventName() { return EVENT_NAME; } - @Override - public short getCoalescingKey() { - // All slide events for a given view can be coalesced. - return 0; - } - @Override protected WritableMap getEventData() { WritableMap eventData = Arguments.createMap(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerStateChangedEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerStateChangedEvent.java index abdb8a38a76d2d..6a9f8e9fb06d01 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerStateChangedEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/events/DrawerStateChangedEvent.java @@ -36,12 +36,6 @@ public String getEventName() { return EVENT_NAME; } - @Override - public short getCoalescingKey() { - // All events for a given view can be coalesced. - return 0; - } - @Override protected WritableMap getEventData() { WritableMap eventData = Arguments.createMap(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java index d1250c7563ff05..646cc5fc59414c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java @@ -31,11 +31,6 @@ public class ReactImageManager extends SimpleViewManager { public static final String REACT_CLASS = "RCTImageView"; - @Override - public String getName() { - return REACT_CLASS; - } - private @Nullable AbstractDraweeControllerBuilder mDraweeControllerBuilder; private @Nullable GlobalImageLoadListener mGlobalImageLoadListener; private final @Nullable Object mCallerContext; @@ -113,6 +108,16 @@ public ReactImageView createViewInstance(ThemedReactContext context) { context, getDraweeControllerBuilder(), mGlobalImageLoadListener, callerContext); } + @Override + public String getName() { + return REACT_CLASS; + } + + @ReactProp(name = "accessible") + public void setAccessible(ReactImageView view, boolean accessible) { + view.setFocusable(accessible); + } + // In JS this is Image.props.source @ReactProp(name = "src") public void setSource(ReactImageView view, @Nullable ReadableArray sources) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java index e10cb5cd33f494..d4f3394269c275 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java @@ -91,6 +91,12 @@ public void setHardwareAccelerated(ReactModalHostView view, boolean hardwareAcce view.setHardwareAccelerated(hardwareAccelerated); } + @Override + @ReactProp(name = "visible") + public void setVisible(ReactModalHostView view, boolean visible) { + // iOS only + } + @Override public void setPresentationStyle(ReactModalHostView view, @Nullable String value) {} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index ac383b9696638a..0304f0e06783e3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -60,6 +60,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView private static boolean sTriedToGetScrollerField = false; private static final String CONTENT_OFFSET_LEFT = "contentOffsetLeft"; private static final String CONTENT_OFFSET_TOP = "contentOffsetTop"; + private static final String SCROLL_AWAY_PADDING_TOP = "scrollAwayPaddingTop"; private int mLayoutDirection; private int mScrollXAfterMeasure = NO_SCROLL_POSITION; @@ -1214,6 +1215,7 @@ public WritableMap getStateUpdate() { WritableMap map = new WritableNativeMap(); map.putDouble(CONTENT_OFFSET_LEFT, PixelUtil.toDIPFromPixel(fabricScrollX)); map.putDouble(CONTENT_OFFSET_TOP, PixelUtil.toDIPFromPixel(scrollY)); + map.putDouble(SCROLL_AWAY_PADDING_TOP, 0); return map; } }); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 90c1ef8283ddad..6a2273b989960b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -30,12 +30,15 @@ import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeMap; import com.facebook.react.common.ReactConstants; +import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.uimanager.FabricViewStateManager; import com.facebook.react.uimanager.MeasureSpecAssertions; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ReactClippingViewGroup; import com.facebook.react.uimanager.ReactClippingViewGroupHelper; import com.facebook.react.uimanager.ViewProps; +import com.facebook.react.uimanager.common.UIManagerType; +import com.facebook.react.uimanager.common.ViewUtil; import com.facebook.react.uimanager.events.NativeGestureUtil; import com.facebook.react.views.view.ReactViewBackgroundManager; import java.lang.reflect.Field; @@ -58,6 +61,7 @@ public class ReactScrollView extends ScrollView private static boolean sTriedToGetScrollerField = false; private static final String CONTENT_OFFSET_LEFT = "contentOffsetLeft"; private static final String CONTENT_OFFSET_TOP = "contentOffsetTop"; + private static final String SCROLL_AWAY_PADDING_TOP = "scrollAwayPaddingTop"; private static final int UNSET_CONTENT_OFFSET = -1; @@ -95,6 +99,9 @@ public class ReactScrollView extends ScrollView private int mFinalAnimatedPositionScrollX; private int mFinalAnimatedPositionScrollY; + private int mScrollAwayPaddingTop = 0; + + private boolean mWaitingForStateUpdateRoundTrip = false; private int mLastStateUpdateScrollX = -1; private int mLastStateUpdateScrollY = -1; @@ -281,10 +288,22 @@ protected void onScrollChanged(int x, int y, int oldX, int oldY) { updateClippingRect(); } - ReactScrollViewHelper.emitScrollEvent( - this, - mOnScrollDispatchHelper.getXFlingVelocity(), - mOnScrollDispatchHelper.getYFlingVelocity()); + // Another potential UpdateState vs onScroll fix: race an UpdateState with every onScroll + // TODO T91209139: if this mechanism works well, port it to HorizontalScrollView + if (ReactFeatureFlags.enableScrollViewStateEventAlwaysRace) { + updateStateOnScroll(); + } + + // TODO T91209139: if this mechanism works well, port it to HorizontalScrollView + boolean deferEvent = + ReactFeatureFlags.enableScrollViewStateEventRaceFix + && (mWaitingForStateUpdateRoundTrip || updateStateOnScroll()); + if (!deferEvent) { + ReactScrollViewHelper.emitScrollEvent( + this, + mOnScrollDispatchHelper.getXFlingVelocity(), + mOnScrollDispatchHelper.getYFlingVelocity()); + } } } @@ -959,35 +978,122 @@ public void setBorderStyle(@Nullable String style) { mReactBackgroundManager.setBorderStyle(style); } + /** + * ScrollAway: This enables a natively-controlled navbar that optionally obscures the top content + * of the ScrollView. Whether or not the navbar is obscuring the React Native surface is + * determined outside of React Native. + * + *

Note: all ScrollViews and HorizontalScrollViews in React have exactly one child: the + * "content" View (see ScrollView.js). That View is non-collapsable so it will never be + * View-flattened away. However, it is possible to pass custom styles into that View. + * + *

If you are using this feature it is assumed that you have full control over this ScrollView + * and that you are **not** overriding the ScrollView content view to pass in a `translateY` + * style. `translateY` must never be set from ReactJS while using this feature! + */ + public void setScrollAwayTopPaddingEnabledUnstable(int topPadding) { + int count = getChildCount(); + + Assertions.assertCondition( + count == 1, "React Native ScrollView always has exactly 1 child; a content View"); + + if (count > 0) { + for (int i = 0; i < count; i++) { + View childView = getChildAt(i); + childView.setTranslationY(topPadding); + } + + // Add the topPadding value as the bottom padding for the ScrollView. + // Otherwise, we'll push down the contents of the scroll view down too + // far off screen. + setPadding(0, 0, 0, topPadding); + } + + updateScrollAwayState(topPadding); + setRemoveClippedSubviews(mRemoveClippedSubviews); + } + + /** + * If we know we are sending a State update, we defer emitting scroll events until the State + * update makes it back to Java. When that happens, we should immediately emit the scroll event. + */ + void onStateUpdate() { + mWaitingForStateUpdateRoundTrip = false; + + // For now we don't dedupe these - we want to send an event whenever the metrics have changed + // from the perspective of C++ + if (ReactFeatureFlags.enableScrollViewStateEventRaceFix) { + ReactScrollViewHelper.emitScrollEvent( + this, + mOnScrollDispatchHelper.getXFlingVelocity(), + mOnScrollDispatchHelper.getYFlingVelocity()); + } + } + /** * Called on any stabilized onScroll change to propagate content offset value to a Shadow Node. */ - private void updateStateOnScroll(final int scrollX, final int scrollY) { + private boolean updateStateOnScroll(final int scrollX, final int scrollY) { + if (ViewUtil.getUIManagerType(getId()) == UIManagerType.DEFAULT) { + return false; + } + // Dedupe events to reduce JNI traffic if (scrollX == mLastStateUpdateScrollX && scrollY == mLastStateUpdateScrollY) { - return; + return false; + } + + // Require a certain delta if we're still scrolling + if (mActivelyScrolling) { + int MIN_DELTA_TO_UPDATE_SCROLL_STATE = ReactFeatureFlags.scrollViewUpdateStateMinScrollDelta; + int deltaX = Math.abs(mLastStateUpdateScrollX - scrollX); + int deltaY = Math.abs(mLastStateUpdateScrollY - scrollY); + if (deltaX < MIN_DELTA_TO_UPDATE_SCROLL_STATE && deltaY < MIN_DELTA_TO_UPDATE_SCROLL_STATE) { + return false; + } } mLastStateUpdateScrollX = scrollX; mLastStateUpdateScrollY = scrollY; + mWaitingForStateUpdateRoundTrip = true; + forceUpdateState(); + + return true; + } + + private boolean updateStateOnScroll() { + return updateStateOnScroll(getScrollX(), getScrollY()); + } + + private void updateScrollAwayState(int scrollAwayPaddingTop) { + if (mScrollAwayPaddingTop == scrollAwayPaddingTop) { + return; + } + + mScrollAwayPaddingTop = scrollAwayPaddingTop; + + forceUpdateState(); + } + + private void forceUpdateState() { + final int scrollX = mLastStateUpdateScrollX; + final int scrollY = mLastStateUpdateScrollY; + final int scrollAwayPaddingTop = mScrollAwayPaddingTop; + mFabricViewStateManager.setState( new FabricViewStateManager.StateUpdateCallback() { @Override public WritableMap getStateUpdate() { - WritableMap map = new WritableNativeMap(); map.putDouble(CONTENT_OFFSET_LEFT, PixelUtil.toDIPFromPixel(scrollX)); map.putDouble(CONTENT_OFFSET_TOP, PixelUtil.toDIPFromPixel(scrollY)); + map.putDouble(SCROLL_AWAY_PADDING_TOP, PixelUtil.toDIPFromPixel(scrollAwayPaddingTop)); return map; } }); } - private void updateStateOnScroll() { - updateStateOnScroll(getScrollX(), getScrollY()); - } - @Override public FabricViewStateManager getFabricViewStateManager() { return mFabricViewStateManager; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index f8add8ad32ae83..c7eed9b6e28f80 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -320,6 +320,7 @@ public void setContentOffset(ReactScrollView view, ReadableMap value) { public Object updateState( ReactScrollView view, ReactStylesDiffMap props, @Nullable StateWrapper stateWrapper) { view.getFabricViewStateManager().setStateWrapper(stateWrapper); + view.onStateUpdate(); return null; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java index 9d4ba87d9b147c..5b0c0c312be4b0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ScrollEvent.java @@ -124,12 +124,6 @@ public String getEventName() { return ScrollEventType.getJSEventName(Assertions.assertNotNull(mScrollEventType)); } - @Override - public short getCoalescingKey() { - // All scroll events for a given view can be coalesced - return 0; - } - @Override public boolean canCoalesce() { // Only SCROLL events can be coalesced, all others can not be diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderEvent.java index 09f764ddb3753d..5b5c85f85925fd 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderEvent.java @@ -39,11 +39,6 @@ public String getEventName() { return EVENT_NAME; } - @Override - public short getCoalescingKey() { - return 0; - } - @Override public void dispatch(RCTEventEmitter rctEventEmitter) { rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSlidingCompleteEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSlidingCompleteEvent.java index 075fd7b46e8a37..44832295f071c0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSlidingCompleteEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSlidingCompleteEvent.java @@ -47,11 +47,6 @@ protected WritableMap getEventData() { return eventData; } - @Override - public short getCoalescingKey() { - return 0; - } - @Override public boolean canCoalesce() { return false; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchEvent.java index 38d0a76c91e210..70f44a0354674b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchEvent.java @@ -46,10 +46,4 @@ protected WritableMap getEventData() { eventData.putBoolean("value", getIsChecked()); return eventData; } - - @Override - public short getCoalescingKey() { - // All switch events for a given view can be coalesced. - return 0; - } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java index e1a20562ae1032..40750ff9ced91b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java @@ -21,7 +21,6 @@ import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerHelper; -import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.ViewManagerDelegate; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; @@ -82,17 +81,11 @@ public long measure( public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ReactContext reactContext = (ReactContext) buttonView.getContext(); - UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); - - if (uiManager == null) { - return; - } - - uiManager - .getEventDispatcher() + int reactTag = buttonView.getId(); + UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag) .dispatchEvent( new ReactSwitchEvent( - UIManagerHelper.getSurfaceId(reactContext), buttonView.getId(), isChecked)); + UIManagerHelper.getSurfaceId(reactContext), reactTag, isChecked)); } }; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java index 53111f412758ff..f350bccf872f58 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java @@ -231,7 +231,14 @@ private Layout measureSpannedText(Spannable text, float width, YogaMeasureMode w // than the width of the text. layout = BoringLayout.make( - text, textPaint, boring.width, alignment, 1.f, 0.f, boring, mIncludeFontPadding); + text, + textPaint, + Math.max(boring.width, 0), + alignment, + 1.f, + 0.f, + boring, + mIncludeFontPadding); } else { // Is used for multiline, boring text and the width is known. diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java index ba871e1679fc1d..f4f618c5ef95e3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java @@ -95,7 +95,7 @@ public Object updateState( return null; } - if (ReactFeatureFlags.mapBufferSerializationEnabled) { + if (ReactFeatureFlags.isMapBufferSerializationEnabled()) { ReadableMapBuffer stateMapBuffer = stateWrapper.getStatDataMapBuffer(); if (stateMapBuffer != null) { return getReactTextUpdate(view, props, stateMapBuffer); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java index 0b88a8a28d9fbb..bbb57f87e88c0d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java @@ -24,6 +24,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.common.logging.FLog; +import com.facebook.react.bridge.ReactNoCrashSoftException; +import com.facebook.react.bridge.ReactSoftException; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableNativeMap; @@ -284,13 +286,20 @@ private static Layout createLayout( } } else if (boring != null && (unconstrainedWidth || boring.width <= width)) { + int boringLayoutWidth = boring.width; + if (boring.width < 0) { + ReactSoftException.logSoftException( + TAG, new ReactNoCrashSoftException("Text width is invalid: " + boring.width)); + boringLayoutWidth = 0; + } + // Is used for single-line, boring text when the width is either unknown or bigger // than the width of the text. layout = BoringLayout.make( text, textPaint, - boring.width, + boringLayoutWidth, Layout.Alignment.ALIGN_NORMAL, 1.f, 0.f, @@ -375,10 +384,6 @@ public static long measureText( } BoringLayout.Metrics boring = BoringLayout.isBoring(text, textPaint); - float desiredWidth = boring == null ? Layout.getDesiredWidth(text, textPaint) : Float.NaN; - - // technically, width should never be negative, but there is currently a bug in - boolean unconstrainedWidth = widthYogaMeasureMode == YogaMeasureMode.UNDEFINED || width < 0; Layout layout = createLayout( diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java index 7af9a540f8644f..422d986a636170 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java @@ -24,6 +24,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.common.logging.FLog; +import com.facebook.react.bridge.ReactNoCrashSoftException; +import com.facebook.react.bridge.ReactSoftException; import com.facebook.react.bridge.WritableArray; import com.facebook.react.common.build.ReactBuildConfig; import com.facebook.react.common.mapbuffer.ReadableMapBuffer; @@ -298,13 +300,19 @@ private static Layout createLayout( } } else if (boring != null && (unconstrainedWidth || boring.width <= width)) { + int boringLayoutWidth = boring.width; + if (boring.width < 0) { + ReactSoftException.logSoftException( + TAG, new ReactNoCrashSoftException("Text width is invalid: " + boring.width)); + boringLayoutWidth = 0; + } // Is used for single-line, boring text when the width is either unknown or bigger // than the width of the text. layout = BoringLayout.make( text, textPaint, - boring.width, + boringLayoutWidth, Layout.Alignment.ALIGN_NORMAL, 1.f, 0.f, diff --git a/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp b/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp index 6534382116eb3c..3503be401f48c5 100644 --- a/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp +++ b/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp @@ -726,8 +726,7 @@ static void jni_YGNodePrintJNI(JNIEnv* env, jobject obj, jlong nativePointer) { const YGNodeRef node = _jlong2YGNodeRef(nativePointer); YGNodePrint( node, - (YGPrintOptions)( - YGPrintOptionsStyle | YGPrintOptionsLayout | YGPrintOptionsChildren)); + (YGPrintOptions) (YGPrintOptionsStyle | YGPrintOptionsLayout | YGPrintOptionsChildren)); #endif } diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index 2a33fa3d0f8294..6027a63f49f15e 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -346,10 +346,10 @@ CatalystInstanceImpl::getNativeCallInvokerHolder() { } jni::alias_ref -CatalystInstanceImpl::getRuntimeExecutor() { +CatalystInstanceImpl::getRuntimeExecutor(bool shouldFlush) { if (!runtimeExecutor_) { - runtimeExecutor_ = jni::make_global( - JRuntimeExecutor::newObjectCxxArgs(instance_->getRuntimeExecutor())); + runtimeExecutor_ = jni::make_global(JRuntimeExecutor::newObjectCxxArgs( + instance_->getRuntimeExecutor(shouldFlush))); } return runtimeExecutor_; } diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h index c40a691232c6a2..fff64a0a79db6f 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h @@ -93,7 +93,8 @@ class CatalystInstanceImpl : public jni::HybridClass { void jniCallJSCallback(jint callbackId, NativeArray *arguments); jni::alias_ref getJSCallInvokerHolder(); jni::alias_ref getNativeCallInvokerHolder(); - jni::alias_ref getRuntimeExecutor(); + jni::alias_ref getRuntimeExecutor( + bool shouldFlush); void setGlobalVariable(std::string propName, std::string &&jsonValue); jlong getJavaScriptContext(); void handleMemoryPressure(int pressureLevel); diff --git a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h index c9eab4170d41f4..d4adbf6d7219d2 100644 --- a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h +++ b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include "OnLoad.h" diff --git a/ReactAndroid/src/main/jni/third-party/boost/Android.mk b/ReactAndroid/src/main/jni/third-party/boost/Android.mk index 089e7d84b5a47a..6092d28c5d932a 100644 --- a/ReactAndroid/src/main/jni/third-party/boost/Android.mk +++ b/ReactAndroid/src/main/jni/third-party/boost/Android.mk @@ -1,9 +1,14 @@ -LOCAL_PATH:= $(call my-dir) +LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +# These ASM files are picked from the boost release separately, +# because the react native version does not include anything outside of headers. +# They are required for Folly futures to compile successfully. +LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/asm/$(TARGET_ARCH)/*.S) + LOCAL_C_INCLUDES := $(LOCAL_PATH)/boost_1_63_0 LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/boost_1_63_0 -LOCAL_MODULE := boost +LOCAL_MODULE := boost include $(BUILD_STATIC_LIBRARY) diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/arm/jump_arm_aapcs_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/arm/jump_arm_aapcs_elf_gas.S new file mode 100644 index 00000000000000..d0f7fa24c6a924 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/arm/jump_arm_aapcs_elf_gas.S @@ -0,0 +1,86 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | v8 | lr | pc | FCTX| DATA| | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl jump_fcontext +.align 2 +.type jump_fcontext,%function +jump_fcontext: + @ save LR as PC + push {lr} + @ save hidden,V1-V8,LR + push {a1,v1-v8,lr} + + @ prepare stack for FPU + sub sp, sp, #64 +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + @ save S16-S31 + vstmia sp, {d8-d15} +#endif + + @ store RSP (pointing to context-data) in A1 + mov a1, sp + + @ restore RSP (pointing to context-data) from A2 + mov sp, a2 + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + @ restore S16-S31 + vldmia sp, {d8-d15} +#endif + @ prepare stack for FPU + add sp, sp, #64 + + @ restore hidden,V1-V8,LR + pop {a4,v1-v8,lr} + + @ return transfer_t from jump + str a1, [a4, #0] + str a3, [a4, #4] + @ pass transfer_t as first arg in context function + @ A1 == FCTX, A2 == DATA + mov a2, a3 + + @ restore PC + pop {pc} +.size jump_fcontext,.-jump_fcontext + +@ Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/arm/make_arm_aapcs_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/arm/make_arm_aapcs_elf_gas.S new file mode 100644 index 00000000000000..993dac10922244 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/arm/make_arm_aapcs_elf_gas.S @@ -0,0 +1,79 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | v8 | lr | pc | FCTX| DATA| | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl make_fcontext +.align 2 +.type make_fcontext,%function +make_fcontext: + @ shift address in A1 to lower 16 byte boundary + bic a1, a1, #15 + + @ reserve space for context-data on context-stack + sub a1, a1, #128 + + @ third arg of make_fcontext() == address of context-function + str a3, [a1, #104] + + @ compute address of returned transfer_t + add a2, a1, #108 + mov a3, a2 + str a3, [a1, #64] + + @ compute abs address of label finish + adr a2, finish + @ save address of finish as return-address for context-function + @ will be entered after context-function returns + str a2, [a1, #100] + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) +#endif + + bx lr @ return pointer to context-data + +finish: + @ exit code is zero + mov a1, #0 + @ exit application + bl _exit@PLT +.size make_fcontext,.-make_fcontext + +@ Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/arm/ontop_arm_aapcs_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/arm/ontop_arm_aapcs_elf_gas.S new file mode 100644 index 00000000000000..9d9198fc552a50 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/arm/ontop_arm_aapcs_elf_gas.S @@ -0,0 +1,91 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | v8 | lr | pc | FCTX| DATA| | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl ontop_fcontext +.align 2 +.type ontop_fcontext,%function +ontop_fcontext: + @ save LR as PC + push {lr} + @ save hidden,V1-V8,LR + push {a1,v1-v8,lr} + + @ prepare stack for FPU + sub sp, sp, #64 +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + @ save S16-S31 + vstmia sp, {d8-d15} +#endif + + @ store RSP (pointing to context-data) in A1 + mov a1, sp + + @ restore RSP (pointing to context-data) from A2 + mov sp, a2 + + @ store parent context in A2 + mov a2, a1 + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + @ restore S16-S31 + vldmia sp, {d8-d15} +#endif + @ prepare stack for FPU + add sp, sp, #64 + + @ restore hidden,V1-V8,LR + pop {a1,v1-v8,lr} + + @ return transfer_t from jump + str a2, [a1, #0] + str a3, [a1, #4] + @ pass transfer_t as first arg in context function + @ A1 == hidden, A2 == FCTX, A3 == DATA + + @ skip PC + add sp, sp, #4 + + @ jump to ontop-function + bx a4 +.size ontop_fcontext,.-ontop_fcontext + +@ Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/jump_arm64_aapcs_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/jump_arm64_aapcs_elf_gas.S new file mode 100644 index 00000000000000..7c0c2fa2f20bff --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/jump_arm64_aapcs_elf_gas.S @@ -0,0 +1,114 @@ +/* + Copyright Edward Nevill + Oliver Kowalke 2015 + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | d8 | d9 | d10 | d11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | d12 | d13 | d14 | d15 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | x19 | x20 | x21 | x22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | x23 | x24 | x25 | x26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | x27 | x28 | FP | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | | | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| | | * + * ------------------------------------------------- * + * | PC | align | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.cpu generic+fp+simd +.text +.align 2 +.global jump_fcontext +.type jump_fcontext, %function +jump_fcontext: + # prepare stack for GP + FPU + sub sp, sp, #0xb0 + + # save d8 - d15 + stp d8, d9, [sp, #0x00] + stp d10, d11, [sp, #0x10] + stp d12, d13, [sp, #0x20] + stp d14, d15, [sp, #0x30] + + # save x19-x30 + stp x19, x20, [sp, #0x40] + stp x21, x22, [sp, #0x50] + stp x23, x24, [sp, #0x60] + stp x25, x26, [sp, #0x70] + stp x27, x28, [sp, #0x80] + stp x29, x30, [sp, #0x90] + + # save LR as PC + str x30, [sp, #0xa0] + + # store RSP (pointing to context-data) in X0 + mov x4, sp + + # restore RSP (pointing to context-data) from X1 + mov sp, x0 + + # load d8 - d15 + ldp d8, d9, [sp, #0x00] + ldp d10, d11, [sp, #0x10] + ldp d12, d13, [sp, #0x20] + ldp d14, d15, [sp, #0x30] + + # load x19-x30 + ldp x19, x20, [sp, #0x40] + ldp x21, x22, [sp, #0x50] + ldp x23, x24, [sp, #0x60] + ldp x25, x26, [sp, #0x70] + ldp x27, x28, [sp, #0x80] + ldp x29, x30, [sp, #0x90] + + # return transfer_t from jump + # pass transfer_t as first arg in context function + # X0 == FCTX, X1 == DATA + mov x0, x4 + + # load pc + ldr x4, [sp, #0xa0] + + # restore stack from GP + FPU + add sp, sp, #0xb0 + + ret x4 +.size jump_fcontext,.-jump_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/make_arm64_aapcs_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/make_arm64_aapcs_elf_gas.S new file mode 100644 index 00000000000000..e71a91cf6f08b9 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/make_arm64_aapcs_elf_gas.S @@ -0,0 +1,85 @@ +/* + Copyright Edward Nevill + Oliver Kowalke 2015 + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | d8 | d9 | d10 | d11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | d12 | d13 | d14 | d15 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | x19 | x20 | x21 | x22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | x23 | x24 | x25 | x26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | x27 | x28 | FP | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | | | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| | | * + * ------------------------------------------------- * + * | PC | align | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.cpu generic+fp+simd +.text +.align 2 +.global make_fcontext +.type make_fcontext, %function +make_fcontext: + # shift address in x0 (allocated stack) to lower 16 byte boundary + and x0, x0, ~0xF + + # reserve space for context-data on context-stack + sub x0, x0, #0xb0 + + # third arg of make_fcontext() == address of context-function + # store address as a PC to jump in + str x2, [x0, #0xa0] + + # save address of finish as return-address for context-function + # will be entered after context-function returns (LR register) + adr x1, finish + str x1, [x0, #0x98] + + ret x30 // return pointer to context-data (x0) + +finish: + # exit code is zero + mov x0, #0 + # exit application + bl _exit + +.size make_fcontext,.-make_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/ontop_arm64_aapcs_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/ontop_arm64_aapcs_elf_gas.S new file mode 100644 index 00000000000000..7e3b047a22c440 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/arm64/ontop_arm64_aapcs_elf_gas.S @@ -0,0 +1,113 @@ +/* + Copyright Edward Nevill + Oliver Kowalke 2015 + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | d8 | d9 | d10 | d11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | d12 | d13 | d14 | d15 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | x19 | x20 | x21 | x22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | x23 | x24 | x25 | x26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | x27 | x28 | FP | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | | | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| | | * + * ------------------------------------------------- * + * | PC | align | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.cpu generic+fp+simd +.text +.align 2 +.global ontop_fcontext +.type ontop_fcontext, %function +ontop_fcontext: + # prepare stack for GP + FPU + sub sp, sp, #0xb0 + + # save d8 - d15 + stp d8, d9, [sp, #0x00] + stp d10, d11, [sp, #0x10] + stp d12, d13, [sp, #0x20] + stp d14, d15, [sp, #0x30] + + # save x19-x30 + stp x19, x20, [sp, #0x40] + stp x21, x22, [sp, #0x50] + stp x23, x24, [sp, #0x60] + stp x25, x26, [sp, #0x70] + stp x27, x28, [sp, #0x80] + stp x29, x30, [sp, #0x90] + + # save LR as PC + str x30, [sp, #0xa0] + + # store RSP (pointing to context-data) in X5 + mov x4, sp + + # restore RSP (pointing to context-data) from X1 + mov sp, x0 + + # load d8 - d15 + ldp d8, d9, [sp, #0x00] + ldp d10, d11, [sp, #0x10] + ldp d12, d13, [sp, #0x20] + ldp d14, d15, [sp, #0x30] + + # load x19-x30 + ldp x19, x20, [sp, #0x40] + ldp x21, x22, [sp, #0x50] + ldp x23, x24, [sp, #0x60] + ldp x25, x26, [sp, #0x70] + ldp x27, x28, [sp, #0x80] + ldp x29, x30, [sp, #0x90] + + # return transfer_t from jump + # pass transfer_t as first arg in context function + # X0 == FCTX, X1 == DATA + mov x0, x4 + + # skip pc + # restore stack from GP + FPU + add sp, sp, #0xb0 + + # jump to ontop-function + ret x2 +.size ontop_fcontext,.-ontop_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/x86/jump_i386_sysv_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/x86/jump_i386_sysv_elf_gas.S new file mode 100644 index 00000000000000..25f01db27d0e04 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/x86/jump_i386_sysv_elf_gas.S @@ -0,0 +1,78 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | | * + * ---------------------------------------------------------------------------------- * + * | to | data | | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl jump_fcontext +.align 2 +.type jump_fcontext,@function +jump_fcontext: + leal -0x18(%esp), %esp /* prepare stack */ + + stmxcsr (%esp) /* save MMX control- and status-word */ + fnstcw 0x4(%esp) /* save x87 control-word */ + + movl %edi, 0x8(%esp) /* save EDI */ + movl %esi, 0xc(%esp) /* save ESI */ + movl %ebx, 0x10(%esp) /* save EBX */ + movl %ebp, 0x14(%esp) /* save EBP */ + + /* store ESP (pointing to context-data) in ECX */ + movl %esp, %ecx + + /* first arg of jump_fcontext() == fcontext to jump to */ + movl 0x20(%esp), %eax + + /* second arg of jump_fcontext() == data to be transferred */ + movl 0x24(%esp), %edx + + /* restore ESP (pointing to context-data) from EAX */ + movl %eax, %esp + + /* address of returned transport_t */ + movl 0x1c(%esp), %eax + /* return parent fcontext_t */ + movl %ecx, (%eax) + /* return data */ + movl %edx, 0x4(%eax) + + movl 0x18(%esp), %ecx /* restore EIP */ + + ldmxcsr (%esp) /* restore MMX control- and status-word */ + fldcw 0x4(%esp) /* restore x87 control-word */ + + movl 0x8(%esp), %edi /* restore EDI */ + movl 0xc(%esp), %esi /* restore ESI */ + movl 0x10(%esp), %ebx /* restore EBX */ + movl 0x14(%esp), %ebp /* restore EBP */ + + leal 0x20(%esp), %esp /* prepare stack */ + + /* jump to context */ + jmp *%ecx +.size jump_fcontext,.-jump_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/x86/make_i386_sysv_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/x86/make_i386_sysv_elf_gas.S new file mode 100644 index 00000000000000..de77e8834daa7f --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/x86/make_i386_sysv_elf_gas.S @@ -0,0 +1,106 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | | * + * ---------------------------------------------------------------------------------- * + * | to | data | | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl make_fcontext +.align 2 +.type make_fcontext,@function +make_fcontext: + /* first arg of make_fcontext() == top of context-stack */ + movl 0x4(%esp), %eax + + /* reserve space for first argument of context-function + eax might already point to a 16byte border */ + leal -0x8(%eax), %eax + + /* shift address in EAX to lower 16 byte boundary */ + andl $-16, %eax + + /* reserve space for context-data on context-stack */ + leal -0x28(%eax), %eax + + /* third arg of make_fcontext() == address of context-function */ + /* stored in EBX */ + movl 0xc(%esp), %ecx + movl %ecx, 0x10(%eax) + + /* save MMX control- and status-word */ + stmxcsr (%eax) + /* save x87 control-word */ + fnstcw 0x4(%eax) + + /* return transport_t */ + /* FCTX == EDI, DATA == ESI */ + leal 0x8(%eax), %ecx + movl %ecx, 0x1c(%eax) + + /* compute abs address of label trampoline */ + call 1f + /* address of trampoline 1 */ +1: popl %ecx + /* compute abs address of label trampoline */ + addl $trampoline-1b, %ecx + /* save address of trampoline as return address */ + /* will be entered after calling jump_fcontext() first time */ + movl %ecx, 0x18(%eax) + + /* compute abs address of label finish */ + call 2f + /* address of label 2 */ +2: popl %ecx + /* compute abs address of label finish */ + addl $finish-2b, %ecx + /* save address of finish as return-address for context-function */ + /* will be entered after context-function returns */ + movl %ecx, 0x14(%eax) + + ret /* return pointer to context-data */ + +trampoline: + /* move transport_t for entering context-function */ + movl %edi, (%esp) + movl %esi, 0x4(%esp) + pushl %ebp + /* jump to context-function */ + jmp *%ebx + +finish: + call 3f + /* address of label 3 */ +3: popl %ebx + /* compute address of GOT and store it in EBX */ + addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx + + /* exit code is zero */ + xorl %eax, %eax + movl %eax, (%esp) + /* exit application */ + call _exit@PLT + hlt +.size make_fcontext,.-make_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/x86/ontop_i386_sysv_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/x86/ontop_i386_sysv_elf_gas.S new file mode 100644 index 00000000000000..d3a6692ffcaf93 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/x86/ontop_i386_sysv_elf_gas.S @@ -0,0 +1,85 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | hidden | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | | * + * ---------------------------------------------------------------------------------- * + * | to | data | | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl ontop_fcontext +.align 2 +.type ontop_fcontext,@function +ontop_fcontext: + leal -0x18(%esp), %esp /* prepare stack */ + + stmxcsr (%esp) /* save MMX control- and status-word */ + fnstcw 0x4(%esp) /* save x87 control-word */ + + movl %edi, 0x8(%esp) /* save EDI */ + movl %esi, 0xc(%esp) /* save ESI */ + movl %ebx, 0x10(%esp) /* save EBX */ + movl %ebp, 0x14(%esp) /* save EBP */ + + /* store ESP (pointing to context-data) in ECX */ + movl %esp, %ecx + + /* first arg of ontop_fcontext() == fcontext to jump to */ + movl 0x20(%esp), %eax + + /* pass parent fcontext_t */ + movl %ecx, 0x20(%eax) + + /* second arg of ontop_fcontext() == data to be transferred */ + movl 0x24(%esp), %ecx + + /* pass data */ + movl %ecx, 0x24(%eax) + + /* third arg of ontop_fcontext() == ontop-function */ + movl 0x28(%esp), %ecx + + /* restore ESP (pointing to context-data) from EAX */ + movl %eax, %esp + + /* address of returned transport_t */ + movl 0x1c(%esp), %eax + /* return parent fcontext_t */ + movl %ecx, (%eax) + /* return data */ + movl %edx, 0x4(%eax) + + ldmxcsr (%esp) /* restore MMX control- and status-word */ + fldcw 0x4(%esp) /* restore x87 control-word */ + + movl 0x8(%esp), %edi /* restore EDI */ + movl 0xc(%esp), %esi /* restore ESI */ + movl 0x10(%esp), %ebx /* restore EBX */ + movl 0x14(%esp), %ebp /* restore EBP */ + + leal 0x18(%esp), %esp /* prepare stack */ + + /* jump to context */ + jmp *%ecx +.size ontop_fcontext,.-ontop_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/jump_x86_64_sysv_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/jump_x86_64_sysv_elf_gas.S new file mode 100644 index 00000000000000..019423886e9bb4 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/jump_x86_64_sysv_elf_gas.S @@ -0,0 +1,76 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * + * ---------------------------------------------------------------------------------- * + * | R15 | RBX | RBP | RIP | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl jump_fcontext +.type jump_fcontext,@function +.align 16 +jump_fcontext: + leaq -0x38(%rsp), %rsp /* prepare stack */ + + stmxcsr (%rsp) /* save MMX control- and status-word */ + fnstcw 0x4(%rsp) /* save x87 control-word */ + + movq %r12, 0x8(%rsp) /* save R12 */ + movq %r13, 0x10(%rsp) /* save R13 */ + movq %r14, 0x18(%rsp) /* save R14 */ + movq %r15, 0x20(%rsp) /* save R15 */ + movq %rbx, 0x28(%rsp) /* save RBX */ + movq %rbp, 0x30(%rsp) /* save RBP */ + + /* store RSP (pointing to context-data) in RAX */ + movq %rsp, %rax + + /* restore RSP (pointing to context-data) from RDI */ + movq %rdi, %rsp + + movq 0x38(%rsp), %r8 /* restore return-address */ + + ldmxcsr (%rsp) /* restore MMX control- and status-word */ + fldcw 0x4(%rsp) /* restore x87 control-word */ + + movq 0x8(%rsp), %r12 /* restore R12 */ + movq 0x10(%rsp), %r13 /* restore R13 */ + movq 0x18(%rsp), %r14 /* restore R14 */ + movq 0x20(%rsp), %r15 /* restore R15 */ + movq 0x28(%rsp), %rbx /* restore RBX */ + movq 0x30(%rsp), %rbp /* restore RBP */ + + leaq 0x40(%rsp), %rsp /* prepare stack */ + + /* return transfer_t from jump */ + /* RAX == fctx, RDX == data */ + movq %rsi, %rdx + /* pass transfer_t as first arg in context function */ + /* RDI == fctx, RSI == data */ + movq %rax, %rdi + + /* indirect jump to context */ + jmp *%r8 +.size jump_fcontext,.-jump_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/make_x86_64_sysv_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/make_x86_64_sysv_elf_gas.S new file mode 100644 index 00000000000000..25a0c00177fc90 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/make_x86_64_sysv_elf_gas.S @@ -0,0 +1,81 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * + * ---------------------------------------------------------------------------------- * + * | R15 | RBX | RBP | RIP | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl make_fcontext +.type make_fcontext,@function +.align 16 +make_fcontext: + /* first arg of make_fcontext() == top of context-stack */ + movq %rdi, %rax + + /* shift address in RAX to lower 16 byte boundary */ + andq $-16, %rax + + /* reserve space for context-data on context-stack */ + /* on context-function entry: (RSP -0x8) % 16 == 0 */ + leaq -0x40(%rax), %rax + + /* third arg of make_fcontext() == address of context-function */ + /* stored in RBX */ + movq %rdx, 0x28(%rax) + + /* save MMX control- and status-word */ + stmxcsr (%rax) + /* save x87 control-word */ + fnstcw 0x4(%rax) + + /* compute abs address of label trampoline */ + leaq trampoline(%rip), %rcx + /* save address of trampoline as return-address for context-function */ + /* will be entered after calling jump_fcontext() first time */ + movq %rcx, 0x38(%rax) + + /* compute abs address of label finish */ + leaq finish(%rip), %rcx + /* save address of finish as return-address for context-function */ + /* will be entered after context-function returns */ + movq %rcx, 0x30(%rax) + + ret /* return pointer to context-data */ + +trampoline: + /* store return address on stack */ + /* fix stack alignment */ + push %rbp + /* jump to context-function */ + jmp *%rbx + +finish: + /* exit code is zero */ + xorq %rdi, %rdi + /* exit application */ + call _exit@PLT + hlt +.size make_fcontext,.-make_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/ontop_x86_64_sysv_elf_gas.S b/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/ontop_x86_64_sysv_elf_gas.S new file mode 100644 index 00000000000000..d2a9373f126040 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/boost/asm/x86_64/ontop_x86_64_sysv_elf_gas.S @@ -0,0 +1,79 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * + * ---------------------------------------------------------------------------------- * + * | R15 | RBX | RBP | RIP | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl ontop_fcontext +.type ontop_fcontext,@function +.align 16 +ontop_fcontext: + /* preserve ontop-function in R8 */ + movq %rdx, %r8 + + leaq -0x38(%rsp), %rsp /* prepare stack */ + + stmxcsr (%rsp) /* save MMX control- and status-word */ + fnstcw 0x4(%rsp) /* save x87 control-word */ + + movq %r12, 0x8(%rsp) /* save R12 */ + movq %r13, 0x10(%rsp) /* save R13 */ + movq %r14, 0x18(%rsp) /* save R14 */ + movq %r15, 0x20(%rsp) /* save R15 */ + movq %rbx, 0x28(%rsp) /* save RBX */ + movq %rbp, 0x30(%rsp) /* save RBP */ + + /* store RSP (pointing to context-data) in RAX */ + movq %rsp, %rax + + /* restore RSP (pointing to context-data) from RDI */ + movq %rdi, %rsp + + ldmxcsr (%rsp) /* restore MMX control- and status-word */ + fldcw 0x4(%rsp) /* restore x87 control-word */ + + movq 0x8(%rsp), %r12 /* restore R12 */ + movq 0x10(%rsp), %r13 /* restore R13 */ + movq 0x18(%rsp), %r14 /* restore R14 */ + movq 0x20(%rsp), %r15 /* restore R15 */ + movq 0x28(%rsp), %rbx /* restore RBX */ + movq 0x30(%rsp), %rbp /* restore RBP */ + + leaq 0x38(%rsp), %rsp /* prepare stack */ + + /* return transfer_t from jump */ + /* RAX == fctx, RDX == data */ + movq %rsi, %rdx + /* pass transfer_t as first arg in context function */ + /* RDI == fctx, RSI == data */ + movq %rax, %rdi + + /* keep return-address on stack */ + + /* indirect jump to context */ + jmp *%r8 +.size ontop_fcontext,.-ontop_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/ReactAndroid/src/main/jni/third-party/fmt/Android.mk b/ReactAndroid/src/main/jni/third-party/fmt/Android.mk new file mode 100644 index 00000000000000..11d070286749aa --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/fmt/Android.mk @@ -0,0 +1,15 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := fmt + +LOCAL_SRC_FILES := \ + src/format.cc + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/ +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include/ + +LOCAL_CFLAGS += -std=c++11 -fexceptions + +include $(BUILD_STATIC_LIBRARY) diff --git a/ReactAndroid/src/main/jni/third-party/folly/Android.mk b/ReactAndroid/src/main/jni/third-party/folly/Android.mk index 1bd5c3e9d137af..469d35aad6e297 100644 --- a/ReactAndroid/src/main/jni/third-party/folly/Android.mk +++ b/ReactAndroid/src/main/jni/third-party/folly/Android.mk @@ -15,12 +15,12 @@ LOCAL_SRC_FILES:= \ folly/json_pointer.cpp \ folly/lang/CString.cpp \ folly/lang/SafeAssert.cpp \ - folly/detail/Demangle.cpp \ folly/detail/UniqueInstance.cpp \ folly/hash/SpookyHashV2.cpp \ folly/container/detail/F14Table.cpp \ folly/ScopeGuard.cpp \ - folly/portability/SysUio.cpp + folly/portability/SysUio.cpp \ + folly/lang/ToAscii.cpp ifeq ($(APP_OPTIM),debug) LOCAL_SRC_FILES += \ @@ -35,9 +35,10 @@ LOCAL_CFLAGS += -fexceptions -fno-omit-frame-pointer -frtti -Wno-sign-compare FOLLY_FLAGS := \ -DFOLLY_NO_CONFIG=1 \ -DFOLLY_HAVE_CLOCK_GETTIME=1 \ - -DFOLLY_HAVE_MEMRCHR=1 \ -DFOLLY_USE_LIBCPP=1 \ - -DFOLLY_MOBILE=1 + -DFOLLY_MOBILE=1 \ + -DFOLLY_HAVE_RECVMMSG=1 \ + -DFOLLY_HAVE_PTHREAD=1 # If APP_PLATFORM in Application.mk targets android-23 above, please comment this line. # NDK uses GNU style stderror_r() after API 23. @@ -50,11 +51,7 @@ LOCAL_EXPORT_CPPFLAGS := $(FOLLY_FLAGS) LOCAL_MODULE := libfolly_json LOCAL_SHARED_LIBRARIES := libglog libdouble-conversion -# Boost is header-only library we pretend to link is statically as -# this way android makefile will automatically setup path to boost header -# file, but except from that this will have no effect, as no c/cpp files -# are part of this static library -LOCAL_STATIC_LIBRARIES := libboost +LOCAL_STATIC_LIBRARIES := libboost libfmt include $(BUILD_SHARED_LIBRARY) @@ -62,26 +59,49 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ folly/ExceptionWrapper.cpp \ + folly/ExceptionString.cpp \ folly/Executor.cpp \ folly/SharedMutex.cpp \ + folly/Singleton.cpp \ + folly/Try.cpp \ folly/concurrency/CacheLocality.cpp \ folly/detail/AsyncTrace.cpp \ folly/detail/AtFork.cpp \ folly/detail/Futex.cpp \ folly/detail/MemoryIdler.cpp \ + folly/detail/SingletonStackTrace.cpp \ folly/detail/StaticSingletonManager.cpp \ folly/detail/ThreadLocalDetail.cpp \ + folly/fibers/Baton.cpp \ + folly/fibers/FiberManager.cpp \ + folly/fibers/Fiber.cpp \ + folly/fibers/GuardPageAllocator.cpp \ + folly/futures/detail/Core.cpp \ + folly/futures/Future.cpp \ + folly/futures/ThreadWheelTimekeeper.cpp \ folly/executors/ExecutorWithPriority.cpp \ folly/executors/InlineExecutor.cpp \ folly/executors/TimedDrivableExecutor.cpp \ folly/executors/QueuedImmediateExecutor.cpp \ + folly/io/async/AsyncTimeout.cpp \ + folly/io/async/EventBase.cpp \ + folly/io/async/EventBaseBackendBase.cpp \ + folly/io/async/EventHandler.cpp \ + folly/io/async/HHWheelTimer.cpp \ folly/io/async/Request.cpp \ + folly/io/async/TimeoutManager.cpp \ + folly/io/async/VirtualEventBase.cpp \ folly/memory/MallctlHelper.cpp \ folly/portability/SysMembarrier.cpp \ folly/synchronization/AsymmetricMemoryBarrier.cpp \ folly/synchronization/Hazptr.cpp \ folly/synchronization/ParkingLot.cpp \ - folly/synchronization/WaitOptions.cpp + folly/synchronization/WaitOptions.cpp \ + folly/synchronization/detail/Sleeper.cpp \ + folly/system/Pid.cpp \ + folly/system/ThreadId.cpp \ + folly/system/ThreadName.cpp + LOCAL_C_INCLUDES := $(LOCAL_PATH) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) @@ -95,14 +115,12 @@ LOCAL_EXPORT_CPPFLAGS := $(FOLLY_FLAGS) LOCAL_MODULE := libfolly_futures LOCAL_SHARED_LIBRARIES := libglog libdouble-conversion libfolly_json -# Boost is header-only library we pretend to link is statically as -# this way android makefile will automatically setup path to boost header -# file, but except from that this will have no effect, as no c/cpp files -# are part of this static library -LOCAL_STATIC_LIBRARIES := libboost +LOCAL_STATIC_LIBRARIES := libboost libevent libfmt include $(BUILD_SHARED_LIBRARY) +$(call import-module,libevent) $(call import-module,glog) $(call import-module,double-conversion) $(call import-module,boost) +$(call import-module,fmt) diff --git a/ReactAndroid/src/main/jni/third-party/libevent/Android.mk b/ReactAndroid/src/main/jni/third-party/libevent/Android.mk new file mode 100644 index 00000000000000..2cffc67fca6775 --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/libevent/Android.mk @@ -0,0 +1,37 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libevent + +LOCAL_SRC_FILES := event.c \ + buffer.c \ + bufferevent.c \ + bufferevent_filter.c \ + bufferevent_pair.c \ + bufferevent_ratelim.c \ + bufferevent_sock.c \ + epoll.c \ + event.c \ + evmap.c \ + evthread.c \ + evthread_pthread.c \ + evutil.c \ + evutil_rand.c \ + evutil_time.c \ + listener.c \ + log.c \ + poll.c \ + signal.c \ + strlcpy.c \ + select.c + +LOCAL_CFLAGS := -DNDEBUG -O2 -Wno-unused-function -Wno-unneeded-internal-declaration -std=c11 + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/ +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include/ + +# link against libc as well +LOCAL_EXPORT_LDLIBS := -lc + +include $(BUILD_STATIC_LIBRARY) diff --git a/ReactAndroid/src/main/jni/third-party/libevent/evconfig-private.h b/ReactAndroid/src/main/jni/third-party/libevent/evconfig-private.h new file mode 100644 index 00000000000000..f6b08e353e841a --- /dev/null +++ b/ReactAndroid/src/main/jni/third-party/libevent/evconfig-private.h @@ -0,0 +1,49 @@ +/* evconfig-private.h. Generated from evconfig-private.h.in by configure. */ +/* evconfig-private.h template - see "Configuration Header Templates" */ +/* in AC manual. Kevin Bowling +#include +/* The size of `size_t', as computed by sizeof. */ +#if SIZE_MAX == UINT64_MAX +#define EVENT__SIZEOF_SIZE_T 8 +#elif SIZE_MAX == UINT32_MAX +#define EVENT__SIZEOF_SIZE_T 4 +#else +#error "No way to infer sizeof size_t" +#endif +#define EVENT__HAVE_UINT64_T 1 +#define EVENT__HAVE_UINT32_T 1 +#define EVENT__HAVE_UINT16_T 1 +#define EVENT__HAVE_UINT8_T 1 +#define EVENT__HAVE_UINTPTR_T 1 +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ +/* Define if libevent should build without support for a debug mode */ +/* #undef EVENT__DISABLE_DEBUG_MODE */ +/* Define if libevent should not allow replacing the mm functions */ +/* #undef EVENT__DISABLE_MM_REPLACEMENT */ +/* Define if libevent should not be compiled with thread support */ +/* #undef EVENT__DISABLE_THREAD_SUPPORT */ +/* Define to 1 if you have the `accept4' function. */ +#define EVENT__HAVE_ACCEPT4 1 +/* Define to 1 if you have the `arc4random' function. */ +#define EVENT__HAVE_ARC4RANDOM 1 +/* Define to 1 if you have the `arc4random_buf' function. */ +#define EVENT__HAVE_ARC4RANDOM_BUF 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_ARPA_INET_H 1 +/* Define to 1 if you have the `clock_gettime' function. */ +#define EVENT__HAVE_CLOCK_GETTIME 1 +/* Define to 1 if you have the declaration of `CTL_KERN', and to 0 if you + don't. */ +/* #undef EVENT__HAVE_DECL_CTL_KERN */ +/* Define to 1 if you have the declaration of `KERN_ARND', and to 0 if you + don't. */ +/* #undef EVENT__HAVE_DECL_KERN_ARND */ +/* Define to 1 if you have the declaration of `KERN_RANDOM', and to 0 if you + don't. */ +/* #undef EVENT__HAVE_DECL_KERN_RANDOM */ +/* Define to 1 if you have the declaration of `RANDOM_UUID', and to 0 if you + don't. */ +/* #undef EVENT__HAVE_DECL_RANDOM_UUID */ +/* Define if /dev/poll is available */ +/* #undef EVENT__HAVE_DEVPOLL */ +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_DLFCN_H 1 +/* Define if your system supports the epoll system calls */ +#define EVENT__HAVE_EPOLL 1 +/* Define to 1 if you have the `epoll_create1' function. */ +#define EVENT__HAVE_EPOLL_CREATE1 1 +/* Define to 1 if you have the `epoll_ctl' function. */ +#define EVENT__HAVE_EPOLL_CTL 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_ERRNO_H 1 +/* Define to 1 if you have ERR_remove_thread_stat(). */ +#undef EVENT__HAVE_ERR_REMOVE_THREAD_STATE +/* Define to 1 if you have the `eventfd' function. */ +#define EVENT__HAVE_EVENTFD 1 +/* Define if your system supports event ports */ +/* #undef EVENT__HAVE_EVENT_PORTS */ +/* Define to 1 if you have the `fcntl' function. */ +#define EVENT__HAVE_FCNTL 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_FCNTL_H 1 +/* Define to 1 if the system has the type `fd_mask'. */ +/* #undef EVENT__HAVE_FD_MASK */ +/* Do we have getaddrinfo()? */ +#define EVENT__HAVE_GETADDRINFO 1 +/* Define to 1 if you have the `getegid' function. */ +#define EVENT__HAVE_GETEGID 1 +/* Define to 1 if you have the `geteuid' function. */ +#define EVENT__HAVE_GETEUID 1 +/* Define this if you have any gethostbyname_r() */ +#define EVENT__HAVE_GETHOSTBYNAME_R 1 +/* Define this if gethostbyname_r takes 3 arguments */ +/* #undef EVENT__HAVE_GETHOSTBYNAME_R_3_ARG */ +/* Define this if gethostbyname_r takes 5 arguments */ +/* #undef EVENT__HAVE_GETHOSTBYNAME_R_5_ARG */ +/* Define this if gethostbyname_r takes 6 arguments */ +#define EVENT__HAVE_GETHOSTBYNAME_R_6_ARG 1 +/* Define to 1 if you have the `getifaddrs' function. */ +/* #undef EVENT__HAVE_GETIFADDRS */ +/* Define to 1 if you have the `getnameinfo' function. */ +#define EVENT__HAVE_GETNAMEINFO 1 +/* Define to 1 if you have the `getprotobynumber' function. */ +#define EVENT__HAVE_GETPROTOBYNUMBER 1 +/* Define to 1 if you have the `getservbyname' function. */ +/* #undef EVENT__HAVE_GETSERVBYNAME */ +/* Define to 1 if you have the `gettimeofday' function. */ +#define EVENT__HAVE_GETTIMEOFDAY 1 +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_IFADDRS_H */ +/* Define to 1 if you have the `inet_ntop' function. */ +#define EVENT__HAVE_INET_NTOP 1 +/* Define to 1 if you have the `inet_pton' function. */ +#define EVENT__HAVE_INET_PTON 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_INTTYPES_H 1 +/* Define to 1 if you have the `issetugid' function. */ +/* #undef EVENT__HAVE_ISSETUGID */ +/* Define to 1 if you have the `kqueue' function. */ +/* #undef EVENT__HAVE_KQUEUE */ +/* Define if the system has zlib */ +#define EVENT__HAVE_LIBZ 1 +/* Define to 1 if you have the `mach_absolute_time' function. */ +#undef HAVE_MACH_ABSOLUTE_TIME +/* Define to 1 if you have the header file. */ +#undef HAVE_MACH_MACH_TIME_H +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_MEMORY_H 1 +/* Define to 1 if you have the `mmap' function. */ +#define EVENT__HAVE_MMAP 1 +/* Define to 1 if you have the `nanosleep' function. */ +#define EVENT__HAVE_NANOSLEEP 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_NETDB_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_NETINET_IN6_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_NETINET_IN_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_NETINET_TCP_H 1 +/* Define if the system has openssl */ +#define EVENT__HAVE_OPENSSL 1 +/* Define to 1 if you have the `pipe' function. */ +/* #undef EVENT__HAVE_PIPE */ +/* Define to 1 if you have the `pipe2' function. */ +/* #undef EVENT__HAVE_PIPE2 */ +/* Define to 1 if you have the `poll' function. */ +#define EVENT__HAVE_POLL 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_POLL_H 1 +/* Define to 1 if you have the `port_create' function. */ +/* #undef EVENT__HAVE_PORT_CREATE */ +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_PORT_H */ +/* Define if you have POSIX threads libraries and header files. */ +/* #undef EVENT__HAVE_PTHREAD */ +/* Define if we have pthreads on this system */ +#define EVENT__HAVE_PTHREADS 1 +/* Define to 1 if you have the `putenv' function. */ +#define EVENT__HAVE_PUTENV 1 +/* Define to 1 if the system has the type `sa_family_t'. */ +#define EVENT__HAVE_SA_FAMILY_T 1 +/* Define to 1 if you have the `select' function. */ +#define EVENT__HAVE_SELECT 1 +/* Define to 1 if you have the `sendfile' function. */ +#define EVENT__HAVE_SENDFILE 1 +/* Define to 1 if you have the `setenv' function. */ +#define EVENT__HAVE_SETENV 1 +/* Define if F_SETFD is defined in */ +#define EVENT__HAVE_SETFD 1 +/* Define to 1 if you have the `setrlimit' function. */ +#define HAVE_SETRLIMIT 1 +/* Define to 1 if you have the `sigaction' function. */ +#define EVENT__HAVE_SIGACTION 1 +/* Define to 1 if you have the `signal' function. */ +#define EVENT__HAVE_SIGNAL 1 +/* Define to 1 if you have the `splice' function. */ +#define EVENT__HAVE_SPLICE 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STDARG_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STDDEF_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STDINT_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STDLIB_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STRINGS_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_STRING_H 1 +/* Define to 1 if you have the `strlcpy' function. */ +#define EVENT__HAVE_STRLCPY 1 +/* Define to 1 if you have the `strsep' function. */ +#define EVENT__HAVE_STRSEP 1 +/* Define to 1 if you have the `strtok_r' function. */ +#define EVENT__HAVE_STRTOK_R 1 +/* Define to 1 if you have the `strtoll' function. */ +#define EVENT__HAVE_STRTOLL 1 +/* Define to 1 if the system has the type `struct addrinfo'. */ +#define EVENT__HAVE_STRUCT_ADDRINFO 1 +/* Define to 1 if the system has the type `struct in6_addr'. */ +#define EVENT__HAVE_STRUCT_IN6_ADDR 1 +/* Define to 1 if `s6_addr16' is a member of `struct in6_addr'. */ +#define EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1 +/* Define to 1 if `s6_addr32' is a member of `struct in6_addr'. */ +#define EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1 +/* Define to 1 if the system has the type `struct sockaddr_in6'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_IN6 1 +/* Define to 1 if `sin6_len' is a member of `struct sockaddr_in6'. */ +/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN */ +/* Define to 1 if `sin_len' is a member of `struct sockaddr_in'. */ +/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ +/* Define to 1 if the system has the type `struct sockaddr_storage'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1 +/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ +#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1 +/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */ +/* #undef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */ +/* Define to 1 if the system has the type `struct so_linger'. */ +#define HAVE_STRUCT_SO_LINGER 1 +/* Define to 1 if you have the `sysctl' function. */ +/* #undef EVENT__HAVE_SYSCTL */ +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_DEVPOLL_H */ +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_EPOLL_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_EVENTFD_H 1 +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_EVENT_H */ +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_IOCTL_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_MMAN_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_PARAM_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_QUEUE_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_SELECT_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_SENDFILE_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_SOCKET_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_STAT_H 1 +/* Define to 1 if you have the header file. */ +/* #undef EVENT__HAVE_SYS_SYSCTL_H */ +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIMERFD_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_TIME_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_TYPES_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_UIO_H 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_SYS_WAIT_H 1 +/* Define if TAILQ_FOREACH is defined in */ +/*#define EVENT__HAVE_TAILQFOREACH 1 */ +/* Define if timeradd is defined in */ +#define EVENT__HAVE_TIMERADD 1 +/* Define if timerclear is defined in */ +#define EVENT__HAVE_TIMERCLEAR 1 +/* Define if timercmp is defined in */ +#define EVENT__HAVE_TIMERCMP 1 +/* Define to 1 if you have the `timerfd_create' function. */ +#define HAVE_TIMERFD_CREATE 1 +/* Define if timerisset is defined in */ +#define EVENT__HAVE_TIMERISSET 1 +/* Define to 1 if the system has the type `uint16_t'. */ +#define EVENT__HAVE_UINT16_T 1 +/* Define to 1 if the system has the type `uint32_t'. */ +#define EVENT__HAVE_UINT32_T 1 +/* Define to 1 if the system has the type `uint64_t'. */ +#define EVENT__HAVE_UINT64_T 1 +/* Define to 1 if the system has the type `uint8_t'. */ +#define EVENT__HAVE_UINT8_T 1 +/* Define to 1 if the system has the type `uintptr_t'. */ +#define EVENT__HAVE_UINTPTR_T 1 +/* Define to 1 if you have the `umask' function. */ +#define EVENT__HAVE_UMASK 1 +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_UNISTD_H 1 +/* Define to 1 if you have the `unsetenv' function. */ +#define EVENT__HAVE_UNSETENV 1 +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 +/* Define to 1 if you have the `vasprintf' function. */ +#define EVENT__HAVE_VASPRINTF 1 +/* Define if waitpid() supports WNOWAIT */ +#define HAVE_WAITPID_WITH_WNOWAIT 1 +/* Define if kqueue works correctly with pipes */ +/* #undef EVENT__HAVE_WORKING_KQUEUE */ +/* Define to 1 if you have the header file. */ +#define EVENT__HAVE_ZLIB_H 1 +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define EVENT__LT_OBJDIR ".libs/" +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef EVENT__NO_MINUS_C_MINUS_O */ +/* Numeric representation of the version */ +#define EVENT__NUMERIC_VERSION 0x02010c00 +/* Name of package */ +#define EVENT__PACKAGE "libevent" +/* Define to the address where bug reports for this package should be sent. */ +#define EVENT__PACKAGE_BUGREPORT "" +/* Define to the full name of this package. */ +#define EVENT__PACKAGE_NAME "" +/* Define to the full name and version of this package. */ +#define EVENT__PACKAGE_STRING "" +/* Define to the one symbol short name of this package. */ +#define EVENT__PACKAGE_TARNAME "" +/* Define to the home page for this package. */ +#define EVENT__PACKAGE_URL "" +/* Define to the version of this package. */ +#define EVENT__PACKAGE_VERSION "" +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef EVENT__PTHREAD_CREATE_JOINABLE */ +/* Define to 1 if you have the ANSI C header files. */ +#define EVENT__STDC_HEADERS 1 +/* Define to 1 if you can safely include both and . */ +#define EVENT__TIME_WITH_SYS_TIME 1 +/* Version number of package */ +#define EVENT__VERSION "2.1.12p-stable" +/* Define to appropriate substitue if compiler doesnt have __func__ */ +/* #undef EVENT____func__ */ +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef EVENT__const */ +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef EVENT____cplusplus +/* #undef EVENT__inline */ +#endif +/* Define to `int' if does not define. */ +/* #undef EVENT__pid_t */ +/* Define to `unsigned int' if does not define. */ +/* #undef EVENT__size_t */ +/* Define to unsigned int if you dont have it */ +/* #undef EVENT__socklen_t */ +/* Define to `int' if does not define. */ +/* #undef EVENT__ssize_t */ +#endif /* event2/event-config.h */ diff --git a/ReactAndroid/src/main/res/views/uimanager/values/strings_unlocalized.xml b/ReactAndroid/src/main/res/views/uimanager/values/strings_unlocalized.xml index a904f57856fb2a..2d239fdbd93def 100644 --- a/ReactAndroid/src/main/res/views/uimanager/values/strings_unlocalized.xml +++ b/ReactAndroid/src/main/res/views/uimanager/values/strings_unlocalized.xml @@ -16,6 +16,10 @@ name="button_description" translatable="false" >Button + Toggle Button Instance::getJSCallInvoker() { return std::static_pointer_cast(jsCallInvoker_); } -RuntimeExecutor Instance::getRuntimeExecutor() { - return nativeToJsBridge_->getRuntimeExecutor(); +RuntimeExecutor Instance::getRuntimeExecutor(bool shouldFlush) { + std::weak_ptr weakNativeToJsBridge = nativeToJsBridge_; + + auto runtimeExecutor = + [weakNativeToJsBridge, + shouldFlush](std::function &&callback) { + if (auto strongNativeToJsBridge = weakNativeToJsBridge.lock()) { + strongNativeToJsBridge->runOnExecutorQueue( + [callback = std::move(callback), + shouldFlush](JSExecutor *executor) { + jsi::Runtime *runtime = + (jsi::Runtime *)executor->getJavaScriptContext(); + try { + callback(*runtime); + if (shouldFlush) { + executor->flush(); + } + } catch (jsi::JSError &originalError) { + handleJSError(*runtime, originalError, true); + } + }); + } + }; + return runtimeExecutor; } std::shared_ptr Instance::getDecoratedNativeCallInvoker( diff --git a/ReactCommon/cxxreact/Instance.h b/ReactCommon/cxxreact/Instance.h index 7cd11f9bdf50b4..dfde400a01d9e8 100644 --- a/ReactCommon/cxxreact/Instance.h +++ b/ReactCommon/cxxreact/Instance.h @@ -134,7 +134,7 @@ class RN_EXPORT Instance { /** * RuntimeExecutor is used by Fabric to access the jsi::Runtime. */ - RuntimeExecutor getRuntimeExecutor(); + RuntimeExecutor getRuntimeExecutor(bool shouldFlush); private: void callNativeModules(folly::dynamic &&calls, bool isEndOfBatch); diff --git a/ReactCommon/cxxreact/NativeToJsBridge.cpp b/ReactCommon/cxxreact/NativeToJsBridge.cpp index d0c13554f28a13..3a695201057bcb 100644 --- a/ReactCommon/cxxreact/NativeToJsBridge.cpp +++ b/ReactCommon/cxxreact/NativeToJsBridge.cpp @@ -340,26 +340,5 @@ std::shared_ptr NativeToJsBridge::getDecoratedNativeCallInvoker( return std::make_shared(m_delegate, nativeInvoker); } -RuntimeExecutor NativeToJsBridge::getRuntimeExecutor() { - auto runtimeExecutor = - [this, isDestroyed = m_destroyed]( - std::function &&callback) { - if (*isDestroyed) { - return; - } - runOnExecutorQueue( - [callback = std::move(callback)](JSExecutor *executor) { - jsi::Runtime *runtime = - (jsi::Runtime *)executor->getJavaScriptContext(); - try { - callback(*runtime); - } catch (jsi::JSError &originalError) { - handleJSError(*runtime, originalError, true); - } - }); - }; - return runtimeExecutor; -} - } // namespace react } // namespace facebook diff --git a/ReactCommon/cxxreact/NativeToJsBridge.h b/ReactCommon/cxxreact/NativeToJsBridge.h index d298f9c27960c2..f9548c59509dbd 100644 --- a/ReactCommon/cxxreact/NativeToJsBridge.h +++ b/ReactCommon/cxxreact/NativeToJsBridge.h @@ -107,12 +107,6 @@ class NativeToJsBridge { std::shared_ptr getDecoratedNativeCallInvoker( std::shared_ptr nativeInvoker); - /** - * RuntimeExecutor is used on Android to access the jsi::Runtime from Fabric - * and TurboModules - */ - RuntimeExecutor getRuntimeExecutor(); - private: // This is used to avoid a race condition where a proxyCallback gets queued // after ~NativeToJsBridge(), on the same thread. In that case, the callback diff --git a/ReactCommon/cxxreact/React-cxxreact.podspec b/ReactCommon/cxxreact/React-cxxreact.podspec index 4e7b322ef21d24..4b9b11793af0d9 100644 --- a/ReactCommon/cxxreact/React-cxxreact.podspec +++ b/ReactCommon/cxxreact/React-cxxreact.podspec @@ -18,7 +18,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' Pod::Spec.new do |s| diff --git a/ReactCommon/hermes/React-hermes.podspec b/ReactCommon/hermes/React-hermes.podspec index cda71b52a67888..3ff062eb81093e 100644 --- a/ReactCommon/hermes/React-hermes.podspec +++ b/ReactCommon/hermes/React-hermes.podspec @@ -16,8 +16,8 @@ else source[:tag] = "v#{version}" end -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -Wno-comma -Wno-shorten-64-to-32' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' Pod::Spec.new do |s| @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.public_header_files = "executor/HermesExecutorFactory.h" s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/..\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\"", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/..\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/libevent/include\"", "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1", } s.header_dir = "reacthermes" @@ -46,8 +46,8 @@ Pod::Spec.new do |s| s.dependency "React-jsinspector", version s.dependency "React-perflogger", version s.dependency "RCT-Folly", folly_version - s.dependency "RCT-Folly/Futures", folly_version s.dependency "DoubleConversion" s.dependency "glog" + s.dependency "RCT-Folly/Futures", folly_version s.dependency "hermes-engine" end diff --git a/ReactCommon/hermes/inspector/chrome/Connection.cpp b/ReactCommon/hermes/inspector/chrome/Connection.cpp index 00cb888156e451..572a07cc2826f6 100644 --- a/ReactCommon/hermes/inspector/chrome/Connection.cpp +++ b/ReactCommon/hermes/inspector/chrome/Connection.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -96,6 +97,9 @@ class Connection::Impl : public inspector::InspectorObserver, void handle(const m::heapProfiler::StartSamplingRequest &req) override; void handle(const m::heapProfiler::StopSamplingRequest &req) override; void handle(const m::heapProfiler::CollectGarbageRequest &req) override; + void handle( + const m::heapProfiler::GetObjectByHeapObjectIdRequest &req) override; + void handle(const m::heapProfiler::GetHeapObjectIdRequest &req) override; void handle(const m::runtime::EvaluateRequest &req) override; void handle(const m::runtime::GetPropertiesRequest &req) override; void handle(const m::runtime::RunIfWaitingForDebuggerRequest &req) override; @@ -637,6 +641,76 @@ void Connection::Impl::handle( .thenError(sendErrorToClient(req.id)); } +void Connection::Impl::handle( + const m::heapProfiler::GetObjectByHeapObjectIdRequest &req) { + uint64_t objID = atoi(req.objectId.c_str()); + folly::Optional group = req.objectGroup; + auto remoteObjPtr = std::make_shared(); + + inspector_ + ->executeIfEnabled( + "HeapProfiler.getObjectByHeapObjectId", + [this, remoteObjPtr, objID, group](const debugger::ProgramState &) { + jsi::Runtime *rt = &getRuntime(); + if (auto *hermesRT = dynamic_cast(rt)) { + jsi::Value val = hermesRT->getObjectForID(objID); + if (val.isNull()) { + return; + } + *remoteObjPtr = m::runtime::makeRemoteObject( + getRuntime(), val, objTable_, group.value_or("")); + } + }) + .via(executor_.get()) + .thenValue([this, id = req.id, remoteObjPtr](auto &&) { + if (!remoteObjPtr->type.empty()) { + m::heapProfiler::GetObjectByHeapObjectIdResponse resp; + resp.id = id; + resp.result = *remoteObjPtr; + sendResponseToClient(resp); + } else { + sendResponseToClient(m::makeErrorResponse( + id, m::ErrorCode::ServerError, "Object is not available")); + } + }) + .thenError(sendErrorToClient(req.id)); +} + +void Connection::Impl::handle( + const m::heapProfiler::GetHeapObjectIdRequest &req) { + // Use a shared_ptr because the stack frame will go away. + std::shared_ptr snapshotID = std::make_shared(0); + + inspector_ + ->executeIfEnabled( + "HeapProfiler.getHeapObjectId", + [this, req, snapshotID](const debugger::ProgramState &) { + if (const jsi::Value *valuePtr = objTable_.getValue(req.objectId)) { + jsi::Runtime *rt = &getRuntime(); + if (auto *hermesRT = dynamic_cast(rt)) { + *snapshotID = hermesRT->getUniqueID(*valuePtr); + } + } + }) + .via(executor_.get()) + .thenValue([this, id = req.id, snapshotID](auto &&) { + if (*snapshotID) { + m::heapProfiler::GetHeapObjectIdResponse resp; + resp.id = id; + // std::to_string is not available on Android, use a std::ostream + // instead. + std::ostringstream stream; + stream << *snapshotID; + resp.heapSnapshotObjectId = stream.str(); + sendResponseToClient(resp); + } else { + sendResponseToClient(m::makeErrorResponse( + id, m::ErrorCode::ServerError, "Object is not available")); + } + }) + .thenError(sendErrorToClient(req.id)); +} + void Connection::Impl::handle(const m::runtime::EvaluateRequest &req) { auto remoteObjPtr = std::make_shared(); diff --git a/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp b/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp index c8aea1ba453469..484719e130e7b6 100644 --- a/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp +++ b/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. -// @generated SignedSource<> +// @generated SignedSource<<522f29c54f207a4f7b5c33af07cf64d0>> #include "MessageTypes.h" @@ -46,6 +46,10 @@ std::unique_ptr Request::fromJsonThrowOnError(const std::string &str) { {"Debugger.stepOver", makeUnique}, {"HeapProfiler.collectGarbage", makeUnique}, + {"HeapProfiler.getHeapObjectId", + makeUnique}, + {"HeapProfiler.getObjectByHeapObjectId", + makeUnique}, {"HeapProfiler.startSampling", makeUnique}, {"HeapProfiler.startTrackingHeapObjects", @@ -730,6 +734,65 @@ void heapProfiler::CollectGarbageRequest::accept( handler.handle(*this); } +heapProfiler::GetHeapObjectIdRequest::GetHeapObjectIdRequest() + : Request("HeapProfiler.getHeapObjectId") {} + +heapProfiler::GetHeapObjectIdRequest::GetHeapObjectIdRequest(const dynamic &obj) + : Request("HeapProfiler.getHeapObjectId") { + assign(id, obj, "id"); + assign(method, obj, "method"); + + dynamic params = obj.at("params"); + assign(objectId, params, "objectId"); +} + +dynamic heapProfiler::GetHeapObjectIdRequest::toDynamic() const { + dynamic params = dynamic::object; + put(params, "objectId", objectId); + + dynamic obj = dynamic::object; + put(obj, "id", id); + put(obj, "method", method); + put(obj, "params", std::move(params)); + return obj; +} + +void heapProfiler::GetHeapObjectIdRequest::accept( + RequestHandler &handler) const { + handler.handle(*this); +} + +heapProfiler::GetObjectByHeapObjectIdRequest::GetObjectByHeapObjectIdRequest() + : Request("HeapProfiler.getObjectByHeapObjectId") {} + +heapProfiler::GetObjectByHeapObjectIdRequest::GetObjectByHeapObjectIdRequest( + const dynamic &obj) + : Request("HeapProfiler.getObjectByHeapObjectId") { + assign(id, obj, "id"); + assign(method, obj, "method"); + + dynamic params = obj.at("params"); + assign(objectId, params, "objectId"); + assign(objectGroup, params, "objectGroup"); +} + +dynamic heapProfiler::GetObjectByHeapObjectIdRequest::toDynamic() const { + dynamic params = dynamic::object; + put(params, "objectId", objectId); + put(params, "objectGroup", objectGroup); + + dynamic obj = dynamic::object; + put(obj, "id", id); + put(obj, "method", method); + put(obj, "params", std::move(params)); + return obj; +} + +void heapProfiler::GetObjectByHeapObjectIdRequest::accept( + RequestHandler &handler) const { + handler.handle(*this); +} + heapProfiler::StartSamplingRequest::StartSamplingRequest() : Request("HeapProfiler.startSampling") {} @@ -1071,6 +1134,42 @@ dynamic debugger::SetInstrumentationBreakpointResponse::toDynamic() const { return obj; } +heapProfiler::GetHeapObjectIdResponse::GetHeapObjectIdResponse( + const dynamic &obj) { + assign(id, obj, "id"); + + dynamic res = obj.at("result"); + assign(heapSnapshotObjectId, res, "heapSnapshotObjectId"); +} + +dynamic heapProfiler::GetHeapObjectIdResponse::toDynamic() const { + dynamic res = dynamic::object; + put(res, "heapSnapshotObjectId", heapSnapshotObjectId); + + dynamic obj = dynamic::object; + put(obj, "id", id); + put(obj, "result", std::move(res)); + return obj; +} + +heapProfiler::GetObjectByHeapObjectIdResponse::GetObjectByHeapObjectIdResponse( + const dynamic &obj) { + assign(id, obj, "id"); + + dynamic res = obj.at("result"); + assign(result, res, "result"); +} + +dynamic heapProfiler::GetObjectByHeapObjectIdResponse::toDynamic() const { + dynamic res = dynamic::object; + put(res, "result", result); + + dynamic obj = dynamic::object; + put(obj, "id", id); + put(obj, "result", std::move(res)); + return obj; +} + heapProfiler::StopSamplingResponse::StopSamplingResponse(const dynamic &obj) { assign(id, obj, "id"); diff --git a/ReactCommon/hermes/inspector/chrome/MessageTypes.h b/ReactCommon/hermes/inspector/chrome/MessageTypes.h index c7092f920def08..2184a223588e4c 100644 --- a/ReactCommon/hermes/inspector/chrome/MessageTypes.h +++ b/ReactCommon/hermes/inspector/chrome/MessageTypes.h @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. -// @generated SignedSource<<0961e921eb7c5201466836c8ce82de73>> +// @generated SignedSource<> #pragma once @@ -72,6 +72,11 @@ using UnserializableValue = std::string; namespace heapProfiler { struct AddHeapSnapshotChunkNotification; struct CollectGarbageRequest; +struct GetHeapObjectIdRequest; +struct GetHeapObjectIdResponse; +struct GetObjectByHeapObjectIdRequest; +struct GetObjectByHeapObjectIdResponse; +using HeapSnapshotObjectId = std::string; struct HeapStatsUpdateNotification; struct LastSeenObjectIdNotification; struct ReportHeapSnapshotProgressNotification; @@ -107,6 +112,9 @@ struct RequestHandler { virtual void handle(const debugger::StepOutRequest &req) = 0; virtual void handle(const debugger::StepOverRequest &req) = 0; virtual void handle(const heapProfiler::CollectGarbageRequest &req) = 0; + virtual void handle(const heapProfiler::GetHeapObjectIdRequest &req) = 0; + virtual void handle( + const heapProfiler::GetObjectByHeapObjectIdRequest &req) = 0; virtual void handle(const heapProfiler::StartSamplingRequest &req) = 0; virtual void handle( const heapProfiler::StartTrackingHeapObjectsRequest &req) = 0; @@ -138,6 +146,9 @@ struct NoopRequestHandler : public RequestHandler { void handle(const debugger::StepOutRequest &req) override {} void handle(const debugger::StepOverRequest &req) override {} void handle(const heapProfiler::CollectGarbageRequest &req) override {} + void handle(const heapProfiler::GetHeapObjectIdRequest &req) override {} + void handle( + const heapProfiler::GetObjectByHeapObjectIdRequest &req) override {} void handle(const heapProfiler::StartSamplingRequest &req) override {} void handle( const heapProfiler::StartTrackingHeapObjectsRequest &req) override {} @@ -464,6 +475,27 @@ struct heapProfiler::CollectGarbageRequest : public Request { void accept(RequestHandler &handler) const override; }; +struct heapProfiler::GetHeapObjectIdRequest : public Request { + GetHeapObjectIdRequest(); + explicit GetHeapObjectIdRequest(const folly::dynamic &obj); + + folly::dynamic toDynamic() const override; + void accept(RequestHandler &handler) const override; + + runtime::RemoteObjectId objectId{}; +}; + +struct heapProfiler::GetObjectByHeapObjectIdRequest : public Request { + GetObjectByHeapObjectIdRequest(); + explicit GetObjectByHeapObjectIdRequest(const folly::dynamic &obj); + + folly::dynamic toDynamic() const override; + void accept(RequestHandler &handler) const override; + + heapProfiler::HeapSnapshotObjectId objectId{}; + folly::Optional objectGroup; +}; + struct heapProfiler::StartSamplingRequest : public Request { StartSamplingRequest(); explicit StartSamplingRequest(const folly::dynamic &obj); @@ -602,6 +634,22 @@ struct debugger::SetInstrumentationBreakpointResponse : public Response { debugger::BreakpointId breakpointId{}; }; +struct heapProfiler::GetHeapObjectIdResponse : public Response { + GetHeapObjectIdResponse() = default; + explicit GetHeapObjectIdResponse(const folly::dynamic &obj); + folly::dynamic toDynamic() const override; + + heapProfiler::HeapSnapshotObjectId heapSnapshotObjectId{}; +}; + +struct heapProfiler::GetObjectByHeapObjectIdResponse : public Response { + GetObjectByHeapObjectIdResponse() = default; + explicit GetObjectByHeapObjectIdResponse(const folly::dynamic &obj); + folly::dynamic toDynamic() const override; + + runtime::RemoteObject result{}; +}; + struct heapProfiler::StopSamplingResponse : public Response { StopSamplingResponse() = default; explicit StopSamplingResponse(const folly::dynamic &obj); diff --git a/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp b/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp index 952e84aac46cb9..f579799bbae538 100644 --- a/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp +++ b/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace facebook { namespace hermes { @@ -2512,6 +2513,86 @@ TEST(ConnectionTests, heapProfilerSampling) { expectNotification(conn); } +TEST(ConnectionTests, heapSnapshotRemoteObject) { + TestContext context; + AsyncHermesRuntime &asyncRuntime = context.runtime(); + std::shared_ptr runtime = asyncRuntime.runtime(); + SyncConnection &conn = context.conn(); + int msgId = 1; + + send(conn, msgId++); + expectExecutionContextCreated(conn); + + asyncRuntime.executeScriptAsync(R"( + storeValue([1, 2, 3]); + debugger; + )"); + expectNotification(conn); + + // We should get a pause before the first statement. + expectNotification(conn); + + { + // Take a heap snapshot first to assign IDs. + m::heapProfiler::TakeHeapSnapshotRequest req; + req.id = msgId++; + req.reportProgress = false; + // We don't need the response because we can directly query for object IDs + // from the runtime. + send(conn, req); + } + + const uint64_t globalObjID = runtime->getUniqueID(runtime->global()); + jsi::Value storedValue = asyncRuntime.awaitStoredValue(); + const uint64_t storedObjID = + runtime->getUniqueID(storedValue.asObject(*runtime)); + + auto testObject = [&msgId, &conn]( + uint64_t objID, + const char *type, + const char *className, + const char *description, + const char *subtype) { + // Get the object by its snapshot ID. + m::heapProfiler::GetObjectByHeapObjectIdRequest req; + req.id = msgId++; + req.objectId = std::to_string(objID); + auto resp = send< + m::heapProfiler::GetObjectByHeapObjectIdRequest, + m::heapProfiler::GetObjectByHeapObjectIdResponse>(conn, req); + EXPECT_EQ(resp.result.type, type); + EXPECT_EQ(resp.result.className, className); + EXPECT_EQ(resp.result.description, description); + if (subtype) { + EXPECT_EQ(resp.result.subtype, subtype); + } + + // Check that fetching the object by heap snapshot ID works. + m::heapProfiler::GetHeapObjectIdRequest idReq; + idReq.id = msgId++; + idReq.objectId = resp.result.objectId.value(); + auto idResp = send< + m::heapProfiler::GetHeapObjectIdRequest, + m::heapProfiler::GetHeapObjectIdResponse>(conn, idReq); + EXPECT_EQ(atoi(idResp.heapSnapshotObjectId.c_str()), objID); + }; + + // Test once before a collection. + testObject(globalObjID, "object", "Object", "Object", nullptr); + testObject(storedObjID, "object", "Array", "Array(3)", "array"); + // Force a collection to move the heap. + runtime->instrumentation().collectGarbage("test"); + // A collection should not disturb the unique ID lookup, and it should be the + // same object as before. Note that it won't have the same remote ID, because + // Hermes doesn't do uniquing. + testObject(globalObjID, "object", "Object", "Object", nullptr); + testObject(storedObjID, "object", "Array", "Array(3)", "array"); + + // Resume and exit. + send(conn, msgId++); + expectNotification(conn); +} + } // namespace chrome } // namespace inspector } // namespace hermes diff --git a/ReactCommon/hermes/inspector/tools/message_types.txt b/ReactCommon/hermes/inspector/tools/message_types.txt index 155c78ae776a02..6267e82ee0ef03 100644 --- a/ReactCommon/hermes/inspector/tools/message_types.txt +++ b/ReactCommon/hermes/inspector/tools/message_types.txt @@ -26,6 +26,8 @@ HeapProfiler.startSampling HeapProfiler.stopSampling HeapProfiler.heapStatsUpdate HeapProfiler.lastSeenObjectId +HeapProfiler.getObjectByHeapObjectId +HeapProfiler.getHeapObjectId Runtime.consoleAPICalled Runtime.evaluate Runtime.executionContextCreated diff --git a/ReactCommon/hermes/inspector/tools/msggen/package.json b/ReactCommon/hermes/inspector/tools/msggen/package.json index bcd465c61e42eb..f9009a21999fb5 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/package.json +++ b/ReactCommon/hermes/inspector/tools/msggen/package.json @@ -20,7 +20,7 @@ "@babel/preset-flow": "^7.2.0", "diff": "3.5.0", "extend": "3.0.2", - "jest": "^24.9.0", + "jest": "^26.6.3", "nwmatcher": "1.4.4", "randomatic": "3.0.0", "sshpk": "1.16.1", diff --git a/ReactCommon/hermes/inspector/tools/msggen/src/Property.js b/ReactCommon/hermes/inspector/tools/msggen/src/Property.js index a3673f0547081e..bfcf5d1a23760a 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/src/Property.js +++ b/ReactCommon/hermes/inspector/tools/msggen/src/Property.js @@ -154,6 +154,7 @@ class RefProperty extends Property { constructor(domain: string, obj: any) { super(domain, obj); this.$ref = obj.$ref; + this.recursive = obj.recursive; } getRefDebuggerName(): ?string { diff --git a/ReactCommon/hermes/inspector/tools/msggen/yarn.lock b/ReactCommon/hermes/inspector/tools/msggen/yarn.lock index 47b1dacda9373d..8ba72b6f94882b 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/yarn.lock +++ b/ReactCommon/hermes/inspector/tools/msggen/yarn.lock @@ -25,6 +25,18 @@ dependencies: "@babel/highlight" "^7.0.0" +"@babel/code-frame@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/compat-data@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.15.tgz#7e8eea42d0b64fda2b375b22d06c605222e848f4" + integrity sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA== + "@babel/core@^7.1.0", "@babel/core@^7.2.0": version "7.7.7" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.7.tgz#ee155d2e12300bcc0cff6a8ad46f2af5063803e9" @@ -45,7 +57,37 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.4.0", "@babel/generator@^7.7.4", "@babel/generator@^7.7.7": +"@babel/core@^7.7.5": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.16.tgz#7756ab24396cc9675f1c3fcd5b79fcce192ea96a" + integrity sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.16" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-module-transforms" "^7.13.14" + "@babel/helpers" "^7.13.16" + "@babel/parser" "^7.13.16" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.15" + "@babel/types" "^7.13.16" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@^7.13.16": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.16.tgz#0befc287031a201d84cdfc173b46b320ae472d14" + integrity sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg== + dependencies: + "@babel/types" "^7.13.16" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/generator@^7.7.4", "@babel/generator@^7.7.7": version "7.7.7" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.7.tgz#859ac733c44c74148e1a72980a64ec84b85f4f45" integrity sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ== @@ -79,6 +121,16 @@ "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/helper-compilation-targets@^7.13.16": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" + integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== + dependencies: + "@babel/compat-data" "^7.13.15" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.14.5" + semver "^6.3.0" + "@babel/helper-create-regexp-features-plugin@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz#6d5762359fd34f4da1500e4cff9955b5299aaf59" @@ -104,6 +156,15 @@ "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/helper-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" + integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== + dependencies: + "@babel/helper-get-function-arity" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/types" "^7.12.13" + "@babel/helper-function-name@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz#ab6e041e7135d436d8f0a3eca15de5b67a341a2e" @@ -113,6 +174,13 @@ "@babel/template" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/helper-get-function-arity@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" + integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== + dependencies: + "@babel/types" "^7.12.13" + "@babel/helper-get-function-arity@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz#cb46348d2f8808e632f0ab048172130e636005f0" @@ -127,6 +195,13 @@ dependencies: "@babel/types" "^7.7.4" +"@babel/helper-member-expression-to-functions@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" + integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== + dependencies: + "@babel/types" "^7.13.12" + "@babel/helper-member-expression-to-functions@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz#356438e2569df7321a8326644d4b790d2122cb74" @@ -134,6 +209,13 @@ dependencies: "@babel/types" "^7.7.4" +"@babel/helper-module-imports@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" + integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== + dependencies: + "@babel/types" "^7.13.12" + "@babel/helper-module-imports@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz#e5a92529f8888bf319a6376abfbd1cebc491ad91" @@ -141,6 +223,20 @@ dependencies: "@babel/types" "^7.7.4" +"@babel/helper-module-transforms@^7.13.14": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef" + integrity sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g== + dependencies: + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-simple-access" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-validator-identifier" "^7.12.11" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.13" + "@babel/types" "^7.13.14" + "@babel/helper-module-transforms@^7.7.4", "@babel/helper-module-transforms@^7.7.5": version "7.7.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz#d044da7ffd91ec967db25cd6748f704b6b244835" @@ -153,6 +249,13 @@ "@babel/types" "^7.7.4" lodash "^4.17.13" +"@babel/helper-optimise-call-expression@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" + integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== + dependencies: + "@babel/types" "^7.12.13" + "@babel/helper-optimise-call-expression@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz#034af31370d2995242aa4df402c3b7794b2dcdf2" @@ -165,6 +268,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== +"@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== + "@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" @@ -183,6 +291,16 @@ "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/helper-replace-supers@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" + integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.12" + "@babel/helper-replace-supers@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz#3c881a6a6a7571275a72d82e6107126ec9e2cdd2" @@ -193,6 +311,13 @@ "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/helper-simple-access@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" + integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== + dependencies: + "@babel/types" "^7.13.12" + "@babel/helper-simple-access@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz#a169a0adb1b5f418cfc19f22586b2ebf58a9a294" @@ -201,6 +326,13 @@ "@babel/template" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/helper-split-export-declaration@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" + integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== + dependencies: + "@babel/types" "^7.12.13" + "@babel/helper-split-export-declaration@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz#57292af60443c4a3622cf74040ddc28e68336fd8" @@ -208,6 +340,16 @@ dependencies: "@babel/types" "^7.7.4" +"@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@babel/helper-validator-option@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== + "@babel/helper-wrap-function@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz#37ab7fed5150e22d9d7266e830072c0cdd8baace" @@ -218,6 +360,15 @@ "@babel/traverse" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/helpers@^7.13.16": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.17.tgz#b497c7a00e9719d5b613b8982bda6ed3ee94caf6" + integrity sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg== + dependencies: + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.17" + "@babel/types" "^7.13.17" + "@babel/helpers@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.4.tgz#62c215b9e6c712dadc15a9a0dcab76c92a940302" @@ -236,11 +387,25 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.7": +"@babel/highlight@^7.12.13": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" + integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.7.4", "@babel/parser@^7.7.7": version "7.7.7" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.7.tgz#1b886595419cf92d811316d5b715a53ff38b4937" integrity sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw== +"@babel/parser@^7.12.13", "@babel/parser@^7.13.16": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.16.tgz#0f18179b0448e6939b1f3f5c4c355a3a9bcdfd37" + integrity sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw== + "@babel/plugin-proposal-async-generator-functions@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz#0351c5ac0a9e927845fffd5b82af476947b7ce6d" @@ -297,6 +462,27 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-dynamic-import@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz#29ca3b4415abfe4a5ec381e903862ad1a54c3aec" @@ -311,6 +497,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz#86e63f7d2e22f9e27129ac4e83ea989a382e86cc" @@ -318,13 +511,48 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.7.4": +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz#47cf220d19d6d0d7b154304701f468fc1cc6ff46" integrity sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz#a3e38f59f4b6233867b4a92dcb0ee05b2c334aa6" @@ -332,6 +560,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + "@babel/plugin-syntax-top-level-await@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz#bd7d8fa7b9fee793a36e4027fd6dd1aa32f946da" @@ -339,6 +581,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" + integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-transform-arrow-functions@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz#76309bd578addd8aee3b379d809c802305a98a12" @@ -656,7 +905,16 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-flow-strip-types" "^7.7.4" -"@babel/template@^7.4.0", "@babel/template@^7.7.4": +"@babel/template@^7.12.13", "@babel/template@^7.3.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" + integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/template@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.4.tgz#428a7d9eecffe27deac0a98e23bf8e3675d2a77b" integrity sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw== @@ -665,7 +923,7 @@ "@babel/parser" "^7.7.4" "@babel/types" "^7.7.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.4": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.4.tgz#9c1e7c60fb679fe4fcfaa42500833333c2058558" integrity sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw== @@ -680,7 +938,21 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.7.4": +"@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.13.15", "@babel/traverse@^7.13.17": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.17.tgz#c85415e0c7d50ac053d758baec98b28b2ecfeea3" + integrity sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.16" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.13.16" + "@babel/types" "^7.13.17" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193" integrity sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA== @@ -689,6 +961,19 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.12.13", "@babel/types@^7.13.12", "@babel/types@^7.13.14", "@babel/types@^7.13.16", "@babel/types@^7.13.17", "@babel/types@^7.3.3": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.17.tgz#48010a115c9fba7588b4437dd68c9469012b38b4" + integrity sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@cnakazawa/watch@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" @@ -697,158 +982,211 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@jest/console@^24.7.1", "@jest/console@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" - integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== dependencies: - "@jest/source-map" "^24.9.0" - chalk "^2.0.1" - slash "^2.0.0" + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" -"@jest/core@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" - integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== - dependencies: - "@jest/console" "^24.7.1" - "@jest/reporters" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" + integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^26.6.2" + jest-util "^26.6.2" + slash "^3.0.0" + +"@jest/core@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" + integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw== + dependencies: + "@jest/console" "^26.6.2" + "@jest/reporters" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" exit "^0.1.2" - graceful-fs "^4.1.15" - jest-changed-files "^24.9.0" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-resolve-dependencies "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - jest-watcher "^24.9.0" - micromatch "^3.1.10" - p-each-series "^1.0.0" - realpath-native "^1.1.0" - rimraf "^2.5.4" - slash "^2.0.0" - strip-ansi "^5.0.0" - -"@jest/environment@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" - integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== - dependencies: - "@jest/fake-timers" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - -"@jest/fake-timers@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" - integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== - dependencies: - "@jest/types" "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - -"@jest/reporters@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" - integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + graceful-fs "^4.2.4" + jest-changed-files "^26.6.2" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-resolve-dependencies "^26.6.3" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + jest-watcher "^26.6.2" + micromatch "^4.0.2" + p-each-series "^2.1.0" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" + integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA== + dependencies: + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + +"@jest/fake-timers@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" + integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA== + dependencies: + "@jest/types" "^26.6.2" + "@sinonjs/fake-timers" "^6.0.1" + "@types/node" "*" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" + jest-util "^26.6.2" + +"@jest/globals@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" + integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/types" "^26.6.2" + expect "^26.6.2" + +"@jest/reporters@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" + integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.2" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-report "^2.0.4" - istanbul-lib-source-maps "^3.0.1" - istanbul-reports "^2.2.6" - jest-haste-map "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" - node-notifier "^5.4.2" - slash "^2.0.0" + graceful-fs "^4.2.4" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^4.0.3" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.2" + jest-haste-map "^26.6.2" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + slash "^3.0.0" source-map "^0.6.0" - string-length "^2.0.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^7.0.0" + optionalDependencies: + node-notifier "^8.0.0" -"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" - integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== +"@jest/source-map@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" + integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA== dependencies: callsites "^3.0.0" - graceful-fs "^4.1.15" + graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" - integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== +"@jest/test-result@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" + integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== dependencies: - "@jest/console" "^24.9.0" - "@jest/types" "^24.9.0" + "@jest/console" "^26.6.2" + "@jest/types" "^26.6.2" "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" - integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== +"@jest/test-sequencer@^26.6.3": + version "26.6.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" + integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw== dependencies: - "@jest/test-result" "^24.9.0" - jest-haste-map "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" + "@jest/test-result" "^26.6.2" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-runner "^26.6.3" + jest-runtime "^26.6.3" -"@jest/transform@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" - integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.9.0" - babel-plugin-istanbul "^5.1.0" - chalk "^2.0.1" + "@jest/types" "^26.6.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.1.15" - jest-haste-map "^24.9.0" - jest-regex-util "^24.9.0" - jest-util "^24.9.0" - micromatch "^3.1.10" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-regex-util "^26.0.0" + jest-util "^26.6.2" + micromatch "^4.0.2" pirates "^4.0.1" - realpath-native "^1.1.0" - slash "^2.0.0" + slash "^3.0.0" source-map "^0.6.1" - write-file-atomic "2.4.1" + write-file-atomic "^3.0.0" -"@jest/types@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" - integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^13.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" + integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== + dependencies: + "@sinonjs/commons" "^1.7.0" -"@types/babel__core@^7.1.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" - integrity sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA== +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": + version "7.1.14" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" + integrity sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -878,11 +1216,30 @@ dependencies: "@babel/types" "^7.3.0" +"@types/babel__traverse@^7.0.4": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" + integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== + dependencies: + "@babel/types" "^7.3.0" + +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== +"@types/istanbul-lib-coverage@^2.0.1": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + "@types/istanbul-lib-report@*": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c" @@ -890,175 +1247,188 @@ dependencies: "@types/istanbul-lib-coverage" "*" -"@types/istanbul-reports@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" - integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== +"@types/istanbul-reports@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" + integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== dependencies: - "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/stack-utils@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" - integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/node@*": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.0.tgz#557dd0da4a6dca1407481df3bbacae0cd6f68042" + integrity sha512-YN1d+ae2MCb4U0mMa+Zlb5lWTdpFShbAj5nmte6lel27waMMBfivrm0prC16p/Di3DyTrmerrYUT8/145HXxVw== + +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + +"@types/prettier@^2.0.0": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" + integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== + +"@types/stack-utils@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" + integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== "@types/yargs-parser@*": version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== -"@types/yargs@^13.0.0": - version "13.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380" - integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ== +"@types/yargs@^15.0.0": + version "15.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" + integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== dependencies: "@types/yargs-parser" "*" -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -1071,33 +1441,38 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abab@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" - integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== -acorn-globals@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" + acorn "^7.1.1" + acorn-walk "^7.1.1" -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^5.5.3: - version "5.7.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" - integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^6.0.1, acorn@^6.2.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== +acorn@^8.1.0: + version "8.2.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.1.tgz#0d36af126fb6755095879c1dc6fd7edf7d60a5fb" + integrity sha512-z716cpm5TX4uzOzILx8PavOE6C6DKshHDw1aQN52M/yNSqE9s5O8SMfyhCCfCJ3HmTL0NkVOi+8a/55T7YB3bg== ajv-errors@^1.0.0: version "1.0.1" @@ -1105,35 +1480,37 @@ ajv-errors@^1.0.0: integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-escapes@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" -ansi-regex@^4.0.0, ansi-regex@^4.1.0: +ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1141,6 +1518,13 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1149,11 +1533,26 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +anymatch@^3.0.3, anymatch@~3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -1169,24 +1568,20 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== dependencies: bn.js "^4.0.0" inherits "^2.0.1" minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" asn1@~0.2.3: version "0.2.4" @@ -1213,27 +1608,17 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - async-each@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -atob@^2.1.1: +atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== @@ -1248,18 +1633,19 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" integrity sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A== -babel-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" - integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== - dependencies: - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/babel__core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.9.0" - chalk "^2.4.2" - slash "^2.0.0" +babel-jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" + integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== + dependencies: + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/babel__core" "^7.1.7" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^26.6.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" babel-plugin-dynamic-import-node@^2.3.0: version "2.3.0" @@ -1268,40 +1654,62 @@ babel-plugin-dynamic-import-node@^2.3.0: dependencies: object.assign "^4.1.0" -babel-plugin-istanbul@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" - integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - find-up "^3.0.0" - istanbul-lib-instrument "^3.3.0" - test-exclude "^5.2.3" - -babel-plugin-jest-hoist@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" - integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== - dependencies: + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" + integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-preset-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" - integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== - dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.9.0" +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" + integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== + dependencies: + babel-plugin-jest-hoist "^26.6.2" + babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base@^0.11.1: version "0.11.2" @@ -1333,6 +1741,11 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -1345,10 +1758,15 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== brace-expansion@^1.1.7: version "1.1.11" @@ -1374,22 +1792,22 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -brorand@^1.0.1: +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= -browser-process-hrtime@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" - integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== - -browser-resolve@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" @@ -1422,26 +1840,28 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" browserify-zlib@^0.2.0: version "0.2.0" @@ -1450,6 +1870,17 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" +browserslist@^4.14.5: + version "4.16.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.5.tgz#952825440bca8913c62d0021334cbe928ef062ae" + integrity sha512-C2HAjrM1AI/djrpAUU/tr4pml1DqLIzJKSLDBXBrNErl9ZCCTXdhwxdJjYc16953+mBWf7Lw+uUJgpgb8cN71A== + dependencies: + caniuse-lite "^1.0.30001214" + colorette "^1.2.2" + electron-to-chromium "^1.3.719" + escalade "^3.1.1" + node-releases "^1.1.71" + browserslist@^4.6.0, browserslist@^4.8.2: version "4.8.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.2.tgz#b45720ad5fbc8713b7253c20766f701c9a694289" @@ -1491,9 +1922,9 @@ builtin-status-codes@^3.0.0: integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= cacache@^12.0.2: - version "12.0.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== dependencies: bluebird "^3.5.5" chownr "^1.1.1" @@ -1536,11 +1967,21 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + caniuse-lite@^1.0.30001015: version "1.0.30001016" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001016.tgz#16ea48d7d6e8caf3cad3295c2d746fe38c4e7f66" integrity sha512-yYQ2QfotceRiH4U+h1Us86WJXtVHDmy3nEKIdYPsZCYnOV5/tMgGbmoIlrMzmh2VXlproqYtVaKeGDBkMZifFA== +caniuse-lite@^1.0.30001214: + version "1.0.30001216" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001216.tgz#47418a082a4f952d14d8964ae739e25efb2060a9" + integrity sha512-1uU+ww/n5WCJRwUcc9UH/W6925Se5aNnem/G5QaSDga2HzvjYMs8vRbekGUN/PnTZ7ezTHcxxTEb9fgiMYwH6Q== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -1553,7 +1994,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2: +chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1562,7 +2003,20 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chokidar@^2.0.2, chokidar@^2.1.8: +chalk@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== @@ -1581,17 +2035,30 @@ chokidar@^2.0.2, chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" +chokidar@^3.4.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + chownr@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" - integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== ci-info@^2.0.0: version "2.0.0" @@ -1606,6 +2073,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +cjs-module-lexer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" + integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -1625,11 +2097,25 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -1645,11 +2131,28 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -1657,7 +2160,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.20.0, commander@~2.20.3: +commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -1702,7 +2205,7 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= -convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.7.0: +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -1740,14 +2243,14 @@ core-util-is@1.0.2, core-util-is@~1.0.0: integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== dependencies: bn.js "^4.1.0" - elliptic "^6.0.0" + elliptic "^6.5.3" -create-hash@^1.1.0, create-hash@^1.1.2: +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== @@ -1758,7 +2261,7 @@ create-hash@^1.1.0, create-hash@^1.1.2: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -1781,6 +2284,15 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -1798,17 +2310,22 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" - integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== dependencies: - cssom "0.3.x" + cssom "~0.3.6" cyclist@^1.0.1: version "1.0.1" @@ -1822,14 +2339,14 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" debug@^2.2.0, debug@^2.3.3: version "2.6.9" @@ -1850,6 +2367,11 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decimal.js@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" + integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -1860,7 +2382,12 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -define-properties@^1.1.2, define-properties@^1.1.3: +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -1902,20 +2429,20 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== devtools-protocol@0.0.730699: version "0.0.730699" resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.730699.tgz#4d18f6a9b7fb7cf3f1ffe73bfe14aad66cf3b2ef" integrity sha512-dprBpuPzVIIXXL6GevzhvWe2wg836h3d5hY+n6IzzHbKLsUh6QlVmcIy15za0J3MhDFbmEH60s6uYsrw/tgBbw== -diff-sequences@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" - integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== diff@3.5.0: version "3.5.0" @@ -1936,12 +2463,12 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== dependencies: - webidl-conversions "^4.0.2" + webidl-conversions "^5.0.0" duplexify@^3.4.2, duplexify@^3.6.0: version "3.7.1" @@ -1966,28 +2493,43 @@ electron-to-chromium@^1.3.322: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8" integrity sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA== -elliptic@^6.0.0: - version "6.5.3" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" - integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== +electron-to-chromium@^1.3.719: + version "1.3.720" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.720.tgz#f5d66df8754d993006b7b2ded15ff7738c58bd94" + integrity sha512-B6zLTxxaOFP4WZm6DrvgRk8kLFYWNhQ5TrHMC0l5WtkMXhU5UbnvWoTfeEwqOruUSlNMhVLfYak7REX6oC5Yfw== + +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" + bn.js "^4.11.9" + brorand "^1.1.0" hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emittery@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" + integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" @@ -1996,19 +2538,19 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== +enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== dependencies: graceful-fs "^4.1.2" memory-fs "^0.5.0" tapable "^1.0.0" errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -2019,44 +2561,28 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0-next.1: - version "1.17.0-next.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0-next.1.tgz#94acc93e20b05a6e96dacb5ab2f1cb3a81fc2172" - integrity sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.0" - string.prototype.trimright "^2.1.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escodegen@^1.9.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" - integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== dependencies: - esprima "^3.1.3" - estraverse "^4.2.0" + esprima "^4.0.1" + estraverse "^5.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: @@ -2070,32 +2596,37 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -esprima@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== events@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" @@ -2123,6 +2654,21 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -2141,17 +2687,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" - integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== +expect@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" + integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== dependencies: - "@jest/types" "^24.9.0" - ansi-styles "^3.2.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.9.0" + "@jest/types" "^26.6.2" + ansi-styles "^4.0.0" + jest-get-type "^26.3.0" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-regex-util "^26.0.0" extend-shallow@^2.0.1: version "2.0.1" @@ -2197,10 +2743,10 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -2220,9 +2766,9 @@ fb-watchman@^2.0.0: bser "2.1.1" figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== file-uri-to-path@1.0.0: version "1.0.0" @@ -2239,6 +2785,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -2255,6 +2808,14 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + flush-write-stream@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -2318,23 +2879,38 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: - version "1.2.11" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" - integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== dependencies: bindings "^1.5.0" nan "^2.12.1" +fsevents@^2.1.2, fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -2342,6 +2918,13 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-stream@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -2362,6 +2945,13 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -2379,38 +2969,27 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.4: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -handlebars@^4.1.2: - version "4.5.3" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" - integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA== - dependencies: - neo-async "^2.6.0" - optimist "^0.6.1" - source-map "^0.6.1" - optionalDependencies: - uglify-js "^3.1.4" - har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== dependencies: - ajv "^6.5.5" + ajv "^6.12.3" har-schema "^2.0.0" has-flag@^3.0.0: @@ -2418,7 +2997,12 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= -has-symbols@^1.0.0, has-symbols@^1.0.1: +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== @@ -2462,12 +3046,13 @@ has@^1.0.3: function-bind "^1.1.1" hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" @@ -2477,7 +3062,7 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hmac-drbg@^1.0.0: +hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= @@ -2491,12 +3076,17 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== dependencies: - whatwg-encoding "^1.0.1" + whatwg-encoding "^1.0.5" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== http-signature@~1.2.0: version "1.2.0" @@ -2512,6 +3102,11 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -2520,22 +3115,22 @@ iconv-lite@0.4.24: safer-buffer ">= 2.1.2 < 3" ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" imurmurhash@^0.1.4: version "0.1.4" @@ -2555,7 +3150,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2570,7 +3165,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -invariant@^2.2.2, invariant@^2.2.4: +invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -2603,16 +3198,18 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -2620,6 +3217,13 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" +is-core-module@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.3.0.tgz#d341652e3408bca69c4671b79a0954a3d349f887" + integrity sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -2634,11 +3238,6 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -2657,6 +3256,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -2679,6 +3283,11 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + is-generator-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" @@ -2691,7 +3300,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -2710,6 +3319,11 @@ is-number@^4.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -2717,26 +3331,22 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" +is-potential-custom-element-name@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -2751,6 +3361,13 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2778,404 +3395,419 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== -istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" +istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" -istanbul-lib-report@^2.0.4: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" -istanbul-lib-source-maps@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== +istanbul-lib-source-maps@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" + integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== dependencies: debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" + istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af" - integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA== - dependencies: - handlebars "^4.1.2" - -jest-changed-files@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" - integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== - dependencies: - "@jest/types" "^24.9.0" - execa "^1.0.0" - throat "^4.0.0" - -jest-cli@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" - integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== - dependencies: - "@jest/core" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" +istanbul-reports@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" + integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0" + integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ== + dependencies: + "@jest/types" "^26.6.2" + execa "^4.0.0" + throat "^5.0.0" + +jest-cli@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" + integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg== + dependencies: + "@jest/core" "^26.6.3" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + chalk "^4.0.0" exit "^0.1.2" - import-local "^2.0.0" + graceful-fs "^4.2.4" + import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" + jest-config "^26.6.3" + jest-util "^26.6.2" + jest-validate "^26.6.2" prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^13.3.0" + yargs "^15.4.1" -jest-config@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" - integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== +jest-config@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" + integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.9.0" - "@jest/types" "^24.9.0" - babel-jest "^24.9.0" - chalk "^2.0.1" + "@jest/test-sequencer" "^26.6.3" + "@jest/types" "^26.6.2" + babel-jest "^26.6.3" + chalk "^4.0.0" + deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^24.9.0" - jest-environment-node "^24.9.0" - jest-get-type "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - micromatch "^3.1.10" - pretty-format "^24.9.0" - realpath-native "^1.1.0" - -jest-diff@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" - integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-docblock@^24.3.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" - integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== - dependencies: - detect-newline "^2.1.0" - -jest-each@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" - integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== - dependencies: - "@jest/types" "^24.9.0" - chalk "^2.0.1" - jest-get-type "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - -jest-environment-jsdom@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" - integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - jsdom "^11.5.1" - -jest-environment-node@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" - integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - -jest-get-type@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" - integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== - -jest-haste-map@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" - integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== - dependencies: - "@jest/types" "^24.9.0" - anymatch "^2.0.0" + graceful-fs "^4.2.4" + jest-environment-jsdom "^26.6.2" + jest-environment-node "^26.6.2" + jest-get-type "^26.3.0" + jest-jasmine2 "^26.6.3" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + micromatch "^4.0.2" + pretty-format "^26.6.2" + +jest-diff@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-docblock@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" + integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w== + dependencies: + detect-newline "^3.0.0" + +jest-each@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" + integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A== + dependencies: + "@jest/types" "^26.6.2" + chalk "^4.0.0" + jest-get-type "^26.3.0" + jest-util "^26.6.2" + pretty-format "^26.6.2" + +jest-environment-jsdom@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" + integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + jest-util "^26.6.2" + jsdom "^16.4.0" + +jest-environment-node@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" + integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag== + dependencies: + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + jest-mock "^26.6.2" + jest-util "^26.6.2" + +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== + +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== + dependencies: + "@jest/types" "^26.6.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.9.0" - micromatch "^3.1.10" + graceful-fs "^4.2.4" + jest-regex-util "^26.0.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + micromatch "^4.0.2" sane "^4.0.3" walker "^1.0.7" optionalDependencies: - fsevents "^1.2.7" + fsevents "^2.1.2" -jest-jasmine2@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" - integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== +jest-jasmine2@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" + integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + "@jest/environment" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" co "^4.6.0" - expect "^24.9.0" + expect "^26.6.2" is-generator-fn "^2.0.0" - jest-each "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - throat "^4.0.0" - -jest-leak-detector@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" - integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== - dependencies: - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-matcher-utils@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" - integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== - dependencies: - chalk "^2.0.1" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-message-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" - integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== + jest-each "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-runtime "^26.6.3" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + pretty-format "^26.6.2" + throat "^5.0.0" + +jest-leak-detector@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af" + integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg== + dependencies: + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-matcher-utils@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" + integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== + dependencies: + chalk "^4.0.0" + jest-diff "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-message-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" + integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" - -jest-mock@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" - integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== - dependencies: - "@jest/types" "^24.9.0" - -jest-pnp-resolver@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" - integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== - -jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" - integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== - -jest-resolve-dependencies@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" - integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== - dependencies: - "@jest/types" "^24.9.0" - jest-regex-util "^24.3.0" - jest-snapshot "^24.9.0" - -jest-resolve@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" - integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== - dependencies: - "@jest/types" "^24.9.0" - browser-resolve "^1.11.3" - chalk "^2.0.1" - jest-pnp-resolver "^1.2.1" - realpath-native "^1.1.0" - -jest-runner@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" - integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.4.2" + "@jest/types" "^26.6.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.2" + pretty-format "^26.6.2" + slash "^3.0.0" + stack-utils "^2.0.2" + +jest-mock@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" + integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + +jest-resolve-dependencies@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" + integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg== + dependencies: + "@jest/types" "^26.6.2" + jest-regex-util "^26.0.0" + jest-snapshot "^26.6.2" + +jest-resolve@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" + integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ== + dependencies: + "@jest/types" "^26.6.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + jest-pnp-resolver "^1.2.2" + jest-util "^26.6.2" + read-pkg-up "^7.0.1" + resolve "^1.18.1" + slash "^3.0.0" + +jest-runner@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" + integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ== + dependencies: + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.7.1" exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-docblock "^24.3.0" - jest-haste-map "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-leak-detector "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" + graceful-fs "^4.2.4" + jest-config "^26.6.3" + jest-docblock "^26.0.0" + jest-haste-map "^26.6.2" + jest-leak-detector "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" + jest-runtime "^26.6.3" + jest-util "^26.6.2" + jest-worker "^26.6.2" source-map-support "^0.5.6" - throat "^4.0.0" - -jest-runtime@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" - integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - chalk "^2.0.1" + throat "^5.0.0" + +jest-runtime@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" + integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw== + dependencies: + "@jest/console" "^26.6.2" + "@jest/environment" "^26.6.2" + "@jest/fake-timers" "^26.6.2" + "@jest/globals" "^26.6.2" + "@jest/source-map" "^26.6.2" + "@jest/test-result" "^26.6.2" + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + cjs-module-lexer "^0.6.0" + collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - realpath-native "^1.1.0" - slash "^2.0.0" - strip-bom "^3.0.0" - yargs "^13.3.0" - -jest-serializer@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" - integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== - -jest-snapshot@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" - integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== + graceful-fs "^4.2.4" + jest-config "^26.6.3" + jest-haste-map "^26.6.2" + jest-message-util "^26.6.2" + jest-mock "^26.6.2" + jest-regex-util "^26.0.0" + jest-resolve "^26.6.2" + jest-snapshot "^26.6.2" + jest-util "^26.6.2" + jest-validate "^26.6.2" + slash "^3.0.0" + strip-bom "^4.0.0" + yargs "^15.4.1" + +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + +jest-snapshot@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" + integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - expect "^24.9.0" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - mkdirp "^0.5.1" + "@jest/types" "^26.6.2" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.0.0" + chalk "^4.0.0" + expect "^26.6.2" + graceful-fs "^4.2.4" + jest-diff "^26.6.2" + jest-get-type "^26.3.0" + jest-haste-map "^26.6.2" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-resolve "^26.6.2" natural-compare "^1.4.0" - pretty-format "^24.9.0" - semver "^6.2.0" - -jest-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" - integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== - dependencies: - "@jest/console" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/source-map" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" + pretty-format "^26.6.2" + semver "^7.3.2" + +jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" + micromatch "^4.0.2" -jest-validate@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" - integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== +jest-validate@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" + integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ== dependencies: - "@jest/types" "^24.9.0" - camelcase "^5.3.1" - chalk "^2.0.1" - jest-get-type "^24.9.0" + "@jest/types" "^26.6.2" + camelcase "^6.0.0" + chalk "^4.0.0" + jest-get-type "^26.3.0" leven "^3.1.0" - pretty-format "^24.9.0" - -jest-watcher@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" - integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== - dependencies: - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.9.0" - string-length "^2.0.0" - -jest-worker@^24.6.0, jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== - dependencies: + pretty-format "^26.6.2" + +jest-watcher@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" + integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ== + dependencies: + "@jest/test-result" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^26.6.2" + string-length "^4.0.1" + +jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" merge-stream "^2.0.0" - supports-color "^6.1.0" + supports-color "^7.0.0" -jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" - integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== +jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef" + integrity sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q== dependencies: - import-local "^2.0.0" - jest-cli "^24.9.0" + "@jest/core" "^26.6.3" + import-local "^3.0.2" + jest-cli "^26.6.3" js-levenshtein@^1.1.3: version "1.1.6" @@ -3187,41 +3819,49 @@ js-levenshtein@^1.1.3: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdom@^11.5.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== - dependencies: - abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" - array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" - domexception "^1.0.1" - escodegen "^1.9.1" - html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" - pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" - symbol-tree "^3.2.2" - tough-cookie "^2.3.4" - w3c-hr-time "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" +jsdom@^16.4.0: + version "16.5.3" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136" + integrity sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA== + dependencies: + abab "^2.0.5" + acorn "^8.1.0" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + html-encoding-sniffer "^2.0.1" + is-potential-custom-element-name "^1.0.0" + nwsapi "^2.2.0" + parse5 "6.0.1" + request "^2.88.2" + request-promise-native "^1.0.9" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.4" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -3234,11 +3874,16 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -3268,6 +3913,13 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -3298,20 +3950,15 @@ kind-of@^5.0.0: integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== - leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -3325,15 +3972,10 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= loader-runner@^2.4.0: version "2.4.0" @@ -3341,12 +3983,12 @@ loader-runner@^2.4.0: integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== loader-utils@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== dependencies: big.js "^5.2.2" - emojis-list "^2.0.0" + emojis-list "^3.0.0" json5 "^1.0.1" locate-path@^3.0.0: @@ -3357,16 +3999,23 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" -lodash@^4.17.13, lodash@^4.17.15: +lodash@^4.17.13: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash@^4.17.19, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + loose-envify@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -3381,6 +4030,13 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -3389,6 +4045,13 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -3396,11 +4059,6 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -3467,6 +4125,14 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.2: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -3487,12 +4153,17 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "1.42.0" +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: +minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= @@ -3504,20 +4175,15 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.1, minimist@^1.2.0: +minimist@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== mississippi@^3.0.0: version "3.0.0" @@ -3543,12 +4209,12 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= +mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: - minimist "0.0.8" + minimist "^1.2.5" move-concurrently@^1.0.1: version "1.0.1" @@ -3573,9 +4239,9 @@ ms@^2.1.1: integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== nanomatch@^1.2.9: version "1.2.13" @@ -3599,10 +4265,10 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== nice-try@^1.0.4: version "1.0.5" @@ -3648,16 +4314,17 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^5.4.2: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== +node-notifier@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" + integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== dependencies: growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" + is-wsl "^2.2.0" + semver "^7.3.2" shellwords "^0.1.1" - which "^1.3.0" + uuid "^8.3.0" + which "^2.0.2" node-releases@^1.1.42: version "1.1.43" @@ -3666,7 +4333,12 @@ node-releases@^1.1.42: dependencies: semver "^6.3.0" -normalize-package-data@^2.3.2: +node-releases@^1.1.71: + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== + +normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -3683,7 +4355,7 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -3695,12 +4367,19 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + nwmatcher@1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" integrity sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ== -nwsapi@^2.0.7: +nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== @@ -3724,12 +4403,7 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.11, object-keys@^1.0.12: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -3751,14 +4425,6 @@ object.assign@^4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" -object.getownpropertydescriptors@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -3773,13 +4439,12 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" + mimic-fn "^2.1.0" optionator@^0.8.1: version "0.8.3" @@ -3798,22 +4463,20 @@ os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" +p-each-series@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" + integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-limit@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" @@ -3824,10 +4487,12 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" p-try@^2.0.0: version "2.2.0" @@ -3835,9 +4500,9 @@ p-try@^2.0.0: integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: - version "1.0.10" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== parallel-transform@^1.1.0: version "1.2.0" @@ -3848,30 +4513,31 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== dependencies: - asn1.js "^4.0.0" + asn1.js "^5.2.0" browserify-aes "^1.0.0" - create-hash "^1.1.0" evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" safe-buffer "^5.1.1" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: + "@babel/code-frame" "^7.0.0" error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== pascalcase@^0.1.1: version "0.1.1" @@ -3893,6 +4559,11 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -3903,22 +4574,20 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -3931,10 +4600,10 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" + integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== pify@^4.0.1: version "4.0.1" @@ -3955,10 +4624,12 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" posix-character-classes@^0.1.0: version "0.1.1" @@ -3970,15 +4641,15 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -pretty-format@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" - integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== +pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== dependencies: - "@jest/types" "^24.9.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" private@^0.1.6: version "0.1.8" @@ -4013,11 +4684,16 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -psl@^1.1.24, psl@^1.1.28: +psl@^1.1.28: version "1.6.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" integrity sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA== +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" @@ -4060,7 +4736,7 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@^1.2.4, punycode@^1.4.1: +punycode@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= @@ -4094,7 +4770,7 @@ randomatic@3.0.0: kind-of "^6.0.0" math-random "^1.0.1" -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -4109,32 +4785,34 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -react-is@^16.8.4: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" - integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -4144,6 +4822,15 @@ read-pkg@^3.0.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -4153,12 +4840,12 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -realpath-native@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" - integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== dependencies: - util.promisify "^1.0.0" + picomatch "^2.2.1" regenerate-unicode-properties@^8.1.0: version "8.1.0" @@ -4217,35 +4904,35 @@ remove-trailing-separator@^1.0.1: integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== dependencies: - lodash "^4.17.15" + lodash "^4.17.19" -request-promise-native@^1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" - integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== +request-promise-native@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== dependencies: - request-promise-core "1.1.3" + request-promise-core "1.1.4" stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.87.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== +request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -4254,7 +4941,7 @@ request@^2.87.0: extend "~3.0.2" forever-agent "~0.6.1" form-data "~2.3.2" - har-validator "~5.1.0" + har-validator "~5.1.3" http-signature "~1.2.0" is-typedarray "~1.0.0" isstream "~0.1.2" @@ -4264,7 +4951,7 @@ request@^2.87.0: performance-now "^2.1.0" qs "~6.5.2" safe-buffer "^5.1.2" - tough-cookie "~2.4.3" + tough-cookie "~2.5.0" tunnel-agent "^0.6.0" uuid "^3.3.2" @@ -4278,28 +4965,23 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== dependencies: - resolve-from "^3.0.0" + resolve-from "^5.0.0" -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - resolve@^1.10.0, resolve@^1.3.2: version "1.14.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.14.1.tgz#9e018c540fcf0c427d678b9931cbf45e984bcaff" @@ -4307,6 +4989,14 @@ resolve@^1.10.0, resolve@^1.3.2: dependencies: path-parse "^1.0.6" +resolve@^1.18.1: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -4319,6 +5009,13 @@ rimraf@^2.5.4, rimraf@^2.6.3: dependencies: glob "^7.1.3" +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -4339,10 +5036,10 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" @@ -4376,10 +5073,12 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" schema-utils@^1.0.0: version "1.0.0" @@ -4400,15 +5099,24 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== +semver@^7.3.2: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" set-blocking@^2.0.0: version "2.0.0" @@ -4445,11 +5153,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" @@ -4470,6 +5190,11 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -4506,17 +5231,17 @@ source-list-map@^2.0.0: integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: - atob "^2.1.1" + atob "^2.1.2" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.6, source-map-support@~0.5.12: +source-map-support@^0.5.6: version "0.5.16" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== @@ -4524,10 +5249,18 @@ source-map-support@^0.5.6, source-map-support@~0.5.12: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" @@ -4539,6 +5272,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -4572,6 +5310,11 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + sshpk@1.16.1, sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -4588,16 +5331,18 @@ sshpk@1.16.1, sshpk@^1.7.0: tweetnacl "~0.14.0" ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== dependencies: figgy-pudding "^3.5.1" -stack-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" - integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== +stack-utils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" + integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + dependencies: + escape-string-regexp "^2.0.0" static-extend@^0.1.1: version "0.1.2" @@ -4644,13 +5389,13 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" + char-regex "^1.0.2" + strip-ansi "^6.0.0" string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" @@ -4661,23 +5406,16 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string.prototype.trimleft@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" -string_decoder@^1.0.0: +string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -4691,13 +5429,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -4705,16 +5436,28 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -4722,14 +5465,22 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: - has-flag "^3.0.0" + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" -symbol-tree@^3.2.2: +symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== @@ -4739,44 +5490,51 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + terser-webpack-plugin@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" - integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== dependencies: cacache "^12.0.2" find-cache-dir "^2.1.0" is-wsl "^1.1.0" schema-utils "^1.0.0" - serialize-javascript "^2.1.2" + serialize-javascript "^4.0.0" source-map "^0.6.1" terser "^4.1.2" webpack-sources "^1.4.0" worker-farm "^1.7.0" terser@^4.1.2: - version "4.4.3" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.3.tgz#401abc52b88869cf904412503b1eb7da093ae2f0" - integrity sha512-0ikKraVtRDKGzHrzkCv5rUNDzqlhmhowOBqC0XqUHFpW+vJ45+20/IFBcebwKfiS2Z9fJin6Eo+F1zLZsxi8RA== + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== dependencies: commander "^2.20.0" source-map "~0.6.1" source-map-support "~0.5.12" -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: - glob "^7.1.3" + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= +throat@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" + integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== through2@^2.0.0: version "2.0.5" @@ -4787,9 +5545,9 @@ through2@^2.0.0: xtend "~4.0.1" timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" @@ -4823,6 +5581,13 @@ to-regex-range@^2.1.0: is-number "^3.0.0" repeat-string "^1.6.1" +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" @@ -4833,7 +5598,7 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@^2.3.3, tough-cookie@^2.3.4: +tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -4841,25 +5606,21 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== dependencies: - psl "^1.1.24" - punycode "^1.4.1" + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= +tr46@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" + integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== dependencies: - punycode "^2.1.0" - -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + punycode "^2.1.1" tty-browserify@0.0.0: version "0.0.0" @@ -4885,19 +5646,38 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -uglify-js@^3.1.4: - version "3.7.2" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.2.tgz#cb1a601e67536e9ed094a92dd1e333459643d3f9" - integrity sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA== - dependencies: - commander "~2.20.3" - source-map "~0.6.1" - unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -4945,6 +5725,11 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -4959,9 +5744,9 @@ upath@^1.1.1: integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -4983,19 +5768,11 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -5015,6 +5792,20 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8-to-istanbul@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.1.tgz#04bfd1026ba4577de5472df4f5e89af49de5edda" + integrity sha512-p0BB09E5FRjx0ELN6RgusIPsSPhtgexSRcKETybEs6IGOTXJSZqfwxp7r//55nnu0f1AxltY5VvdVqy2vZf9AA== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -5037,12 +5828,19 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -w3c-hr-time@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" - integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== dependencies: - browser-process-hrtime "^0.1.2" + xml-name-validator "^3.0.0" walker@^1.0.7, walker@~1.0.5: version "1.0.7" @@ -5051,19 +5849,33 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: - chokidar "^2.0.2" graceful-fs "^4.1.2" neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== webpack-sources@^1.4.0, webpack-sources@^1.4.1: version "1.4.3" @@ -5074,86 +5886,79 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1: source-map "~0.6.1" webpack@^4.41.0: - version "4.41.4" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.4.tgz#4bec4125224bdf50efa8be6226c19047599cd034" - integrity sha512-Lc+2uB6NjpCWsHI3trkoISOI64h9QYIXenbEWj3bn3oyjfB1lEBXjWAfAyY2sM0rZn41oD5V91OLwKRwS6Wp8Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" + version "4.46.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" + integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" ajv "^6.10.2" ajv-keywords "^3.4.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" + enhanced-resolve "^4.5.0" eslint-scope "^4.0.3" json-parse-better-errors "^1.0.2" loader-runner "^2.4.0" loader-utils "^1.2.3" memory-fs "^0.4.1" micromatch "^3.1.10" - mkdirp "^0.5.1" + mkdirp "^0.5.3" neo-async "^2.6.1" node-libs-browser "^2.2.1" schema-utils "^1.0.0" tapable "^1.1.3" terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" + watchpack "^1.7.4" webpack-sources "^1.4.1" -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: +whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: +whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" + integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + lodash "^4.7.0" + tr46 "^2.0.2" + webidl-conversions "^6.1.0" which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.9, which@^1.3.0: +which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" +which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -5170,54 +5975,64 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" - integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: - graceful-fs "^4.1.11" imurmurhash "^0.1.4" + is-typedarray "^1.0.0" signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" +ws@^7.4.4: + version "7.4.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" + integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@^13.1.1: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yargs-parser@^15.0.0: version "15.0.0" @@ -5227,12 +6042,21 @@ yargs-parser@^15.0.0: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@^13.3.0: - version "13.3.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" - integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^14.2.0: + version "14.2.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.2.tgz#2769564379009ff8597cdd38fba09da9b493c4b5" + integrity sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA== dependencies: cliui "^5.0.0" + decamelize "^1.2.0" find-up "^3.0.0" get-caller-file "^2.0.1" require-directory "^2.1.1" @@ -5241,21 +6065,21 @@ yargs@^13.3.0: string-width "^3.0.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^13.1.1" + yargs-parser "^15.0.0" -yargs@^14.2.0: - version "14.2.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.2.tgz#2769564379009ff8597cdd38fba09da9b493c4b5" - integrity sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA== +yargs@^15.4.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== dependencies: - cliui "^5.0.0" + cliui "^6.0.0" decamelize "^1.2.0" - find-up "^3.0.0" + find-up "^4.1.0" get-caller-file "^2.0.1" require-directory "^2.1.1" require-main-filename "^2.0.0" set-blocking "^2.0.0" - string-width "^3.0.0" + string-width "^4.2.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^15.0.0" + yargs-parser "^18.1.2" diff --git a/ReactCommon/jsi/JSCRuntime.cpp b/ReactCommon/jsi/JSCRuntime.cpp index b6e6062847cc87..c9465b33dff585 100644 --- a/ReactCommon/jsi/JSCRuntime.cpp +++ b/ReactCommon/jsi/JSCRuntime.cpp @@ -50,6 +50,9 @@ class JSCRuntime : public jsi::Runtime { jsi::Value evaluateJavaScript( const std::shared_ptr &buffer, const std::string &sourceURL) override; + + bool drainMicrotasks(int maxMicrotasksHint = -1) override; + jsi::Object global() override; std::string description() override; @@ -432,6 +435,10 @@ jsi::Value JSCRuntime::evaluateJavaScript( return createValue(res); } +bool JSCRuntime::drainMicrotasks(int maxMicrotasksHint) { + return true; +} + jsi::Object JSCRuntime::global() { return createObject(JSContextGetGlobalObject(ctx_)); } diff --git a/ReactCommon/jsi/React-jsi.podspec b/ReactCommon/jsi/React-jsi.podspec index 6c1cf2ad3e20c5..9b32264f9072b4 100644 --- a/ReactCommon/jsi/React-jsi.podspec +++ b/ReactCommon/jsi/React-jsi.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' Pod::Spec.new do |s| diff --git a/ReactCommon/jsi/jsi/decorator.h b/ReactCommon/jsi/jsi/decorator.h index fa8287313c0f40..be6f4f568b68ec 100644 --- a/ReactCommon/jsi/jsi/decorator.h +++ b/ReactCommon/jsi/jsi/decorator.h @@ -126,6 +126,9 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation { const std::shared_ptr& js) override { return plain().evaluatePreparedJavaScript(js); } + bool drainMicrotasks(int maxMicrotasksHint) override { + return plain().drainMicrotasks(maxMicrotasksHint); + } Object global() override { return plain().global(); } @@ -491,6 +494,10 @@ class WithRuntimeDecorator : public RuntimeDecorator { Around around{with_}; return RD::evaluatePreparedJavaScript(js); } + bool drainMicrotasks(int maxMicrotasksHint) override { + Around around{with_}; + return RD::drainMicrotasks(maxMicrotasksHint); + } Object global() override { Around around{with_}; return RD::global(); diff --git a/ReactCommon/jsi/jsi/jsi.h b/ReactCommon/jsi/jsi/jsi.h index 67149a80b10a1c..ae64498f03f9d1 100644 --- a/ReactCommon/jsi/jsi/jsi.h +++ b/ReactCommon/jsi/jsi/jsi.h @@ -185,6 +185,35 @@ class JSI_EXPORT Runtime { virtual Value evaluatePreparedJavaScript( const std::shared_ptr& js) = 0; + /// Drain the JavaScript VM internal Microtask (a.k.a. Job in ECMA262) queue. + /// + /// \param maxMicrotasksHint a hint to tell an implementation that it should + /// make a best effort not execute more than the given number. It's default + /// to -1 for infinity (unbounded execution). + /// \return true if the queue is drained or false if there is more work to do. + /// + /// When there were exceptions thrown from the execution of microtasks, + /// implementations shall discard the exceptional jobs. An implementation may + /// \throw a \c JSError object to signal the hosts to handle. In that case, an + /// implementation may or may not suspend the draining. + /// + /// Hosts may call this function again to resume the draining if it was + /// suspended due to either exceptions or the \p maxMicrotasksHint bound. + /// E.g. a host may repetitively invoke this function until the queue is + /// drained to implement the "microtask checkpint" defined in WHATWG HTML + /// event loop: https://html.spec.whatwg.org/C#perform-a-microtask-checkpoint. + /// + /// Note that error propagation is only a concern if a host needs to implement + /// `queueMicrotask`, a recent API that allows enqueueing aribitary functions + /// (hence may throw) as microtasks. Exceptions from ECMA-262 Promise Jobs are + /// handled internally to VMs and are never propagrated to hosts. + /// + /// This API offers some queue management to hosts at its best effort due to + /// different behaviors and limitations imposed by different VMs and APIs. By + /// the time this is written, An implementation may swallow exceptions (JSC), + /// may not pause (V8), and may not support bounded executions. + virtual bool drainMicrotasks(int maxMicrotasksHint = -1) = 0; + /// \return the global object virtual Object global() = 0; diff --git a/ReactCommon/jsiexecutor/React-jsiexecutor.podspec b/ReactCommon/jsiexecutor/React-jsiexecutor.podspec index e0a050dd0b44d8..7f2dbbc7ec3e94 100644 --- a/ReactCommon/jsiexecutor/React-jsiexecutor.podspec +++ b/ReactCommon/jsiexecutor/React-jsiexecutor.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' Pod::Spec.new do |s| diff --git a/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp b/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp index f1d4c5170604cf..f1d16bacb399ab 100644 --- a/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp +++ b/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp @@ -7,6 +7,7 @@ #include "jsireact/JSIExecutor.h" +#include #include #include #include @@ -204,6 +205,30 @@ void JSIExecutor::registerBundle( ReactMarker::REGISTER_JS_SEGMENT_STOP, tag.c_str()); } +// Looping on \c drainMicrotasks until it completes or hits the retries bound. +static void performMicrotaskCheckpoint(jsi::Runtime &runtime) { + uint8_t retries = 0; + // A heuristic number to guard inifinite or absurd numbers of retries. + const static unsigned int kRetriesBound = 255; + + while (retries < kRetriesBound) { + try { + // The default behavior of \c drainMicrotasks is unbounded execution. + // We may want to make it bounded in the future. + if (runtime.drainMicrotasks()) { + break; + } + } catch (jsi::JSError &error) { + handleJSError(runtime, error, true); + } + retries++; + } + + if (retries == kRetriesBound) { + throw std::runtime_error("Hits microtasks retries bound."); + } +} + void JSIExecutor::callFunction( const std::string &moduleId, const std::string &methodId, @@ -240,6 +265,8 @@ void JSIExecutor::callFunction( std::runtime_error("Error calling " + moduleId + "." + methodId)); } + performMicrotaskCheckpoint(*runtime_); + callNativeModules(ret, true); } @@ -259,6 +286,8 @@ void JSIExecutor::invokeCallback( folly::to("Error invoking callback ", callbackId))); } + performMicrotaskCheckpoint(*runtime_); + callNativeModules(ret, true); } @@ -394,7 +423,9 @@ void JSIExecutor::callNativeModules(const Value &queue, bool isEndOfBatch) { void JSIExecutor::flush() { SystraceSection s("JSIExecutor::flush"); if (flushedQueue_) { - callNativeModules(flushedQueue_->call(*runtime_), true); + Value ret = flushedQueue_->call(*runtime_); + performMicrotaskCheckpoint(*runtime_); + callNativeModules(ret, true); return; } @@ -410,7 +441,9 @@ void JSIExecutor::flush() { // If calls were made, we bind to the JS bridge methods, and use them to // get the pending queue of native calls. bindBridge(); - callNativeModules(flushedQueue_->call(*runtime_), true); + Value ret = flushedQueue_->call(*runtime_); + performMicrotaskCheckpoint(*runtime_); + callNativeModules(ret, true); } else if (delegate_) { // If we have a delegate, we need to call it; we pass a null list to // callNativeModules, since we know there are no native calls, without diff --git a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.h b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.h index fe61116eee5256..7a76cfc890df59 100644 --- a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.h +++ b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.h @@ -101,20 +101,8 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule { } // namespace facebook @protocol RCTTurboModule -@optional -/** - * Used by TurboModules to get access to other TurboModules. - * - * Usage: - * Place `@synthesize turboModuleRegistry = _turboModuleRegistry` - * in the @implementation section of your TurboModule. - */ -@property (nonatomic, weak) id turboModuleRegistry; - -@required - (std::shared_ptr)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params; - @end /** diff --git a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm index b730492b9033d8..d3a92a13c26fef 100644 --- a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm +++ b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm @@ -171,15 +171,12 @@ static int32_t getUniqueId() convertJSIFunctionToCallback(jsi::Runtime &runtime, const jsi::Function &value, std::shared_ptr jsInvoker) { auto weakWrapper = CallbackWrapper::createWeak(value.getFunction(runtime), runtime, jsInvoker); - RCTBlockGuard *blockGuard; - if (RCTTurboModuleBlockGuardEnabled()) { - blockGuard = [[RCTBlockGuard alloc] initWithCleanup:^() { - auto strongWrapper = weakWrapper.lock(); - if (strongWrapper) { - strongWrapper->destroy(); - } - }]; - } + RCTBlockGuard *blockGuard = [[RCTBlockGuard alloc] initWithCleanup:^() { + auto strongWrapper = weakWrapper.lock(); + if (strongWrapper) { + strongWrapper->destroy(); + } + }]; BOOL __block wrapperWasCalled = NO; RCTResponseSenderBlock callback = ^(NSArray *responses) { @@ -254,6 +251,21 @@ static int32_t getUniqueId() __block BOOL resolveWasCalled = NO; __block BOOL rejectWasCalled = NO; + RCTBlockGuard *blockGuard; + if (RCTTurboModulePromisesBlockGuardEnabled()) { + blockGuard = [[RCTBlockGuard alloc] initWithCleanup:^() { + auto strongResolveWrapper = weakResolveWrapper.lock(); + if (strongResolveWrapper) { + strongResolveWrapper->destroy(); + } + + auto strongRejectWrapper = weakRejectWrapper.lock(); + if (strongRejectWrapper) { + strongRejectWrapper->destroy(); + } + }]; + } + RCTPromiseResolveBlock resolveBlock = ^(id result) { if (rejectWasCalled) { RCTLogError(@"%s: Tried to resolve a promise after it's already been rejected.", moduleMethod.c_str()); @@ -271,7 +283,7 @@ static int32_t getUniqueId() return; } - strongResolveWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, result]() { + strongResolveWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, result, blockGuard]() { auto strongResolveWrapper2 = weakResolveWrapper.lock(); auto strongRejectWrapper2 = weakRejectWrapper.lock(); if (!strongResolveWrapper2 || !strongRejectWrapper2) { @@ -284,6 +296,7 @@ static int32_t getUniqueId() strongResolveWrapper2->destroy(); strongRejectWrapper2->destroy(); + (void)blockGuard; }); resolveWasCalled = YES; @@ -307,7 +320,7 @@ static int32_t getUniqueId() } NSDictionary *jsError = RCTJSErrorFromCodeMessageAndNSError(code, message, error); - strongRejectWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, jsError]() { + strongRejectWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, jsError, blockGuard]() { auto strongResolveWrapper2 = weakResolveWrapper.lock(); auto strongRejectWrapper2 = weakRejectWrapper.lock(); if (!strongResolveWrapper2 || !strongRejectWrapper2) { @@ -320,6 +333,7 @@ static int32_t getUniqueId() strongResolveWrapper2->destroy(); strongRejectWrapper2->destroy(); + (void)blockGuard; }); rejectWasCalled = YES; diff --git a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.h b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.h index 5e112440b8cd41..2b9c4731940179 100644 --- a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.h +++ b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.h @@ -45,7 +45,6 @@ jsInvoker:(std::shared_ptr)jsInvoker; - (void)installJSBindingWithRuntimeExecutor:(facebook::react::RuntimeExecutor)runtimeExecutor; -- (void)setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider)bridgelessComponentViewProvider; - (void)invalidate; diff --git a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm index 8d755a6961b359..6e683df0d4af3d 100644 --- a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm +++ b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm @@ -18,6 +18,7 @@ #import #import #import +#import #import #import #import @@ -174,7 +175,6 @@ @implementation RCTTurboModuleManager { std::atomic _invalidating; RCTModuleRegistry *_moduleRegistry; - RCTViewRegistry *_viewRegistry_DEPRECATED; } - (instancetype)initWithBridge:(RCTBridge *)bridge @@ -190,9 +190,6 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge [_moduleRegistry setBridge:bridge]; [_moduleRegistry setTurboModuleRegistry:self]; - _viewRegistry_DEPRECATED = [RCTViewRegistry new]; - [_viewRegistry_DEPRECATED setBridge:bridge]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bridgeWillInvalidateModules:) name:RCTBridgeWillInvalidateModulesNotification @@ -205,11 +202,6 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge return self; } -- (void)setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider)viewProvider -{ - [_viewRegistry_DEPRECATED setBridgelessComponentViewProvider:viewProvider]; -} - - (void)notifyAboutTurboModuleSetup:(const char *)name { NSString *moduleName = [[NSString alloc] initWithUTF8String:name]; @@ -277,6 +269,9 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name Class moduleClass = [module class]; dispatch_queue_t methodQueue = (dispatch_queue_t)objc_getAssociatedObject(module, &kAssociatedMethodQueueKey); + if (methodQueue == nil) { + RCTLogError(@"TurboModule \"%@\" was not associated with a method queue.", moduleClass); + } /** * Step 2c: Create and native CallInvoker from the TurboModule's method queue. @@ -505,10 +500,6 @@ - (TurboModuleHolder *)_getOrCreateTurboModuleHolder:(const char *)moduleName TurboModulePerfLogger::moduleCreateSetUpStart(moduleName, moduleId); - if ([module respondsToSelector:@selector(setTurboModuleRegistry:)]) { - [module setTurboModuleRegistry:self]; - } - /** * It is reasonable for NativeModules to not want/need the bridge. * In such cases, they won't have `@synthesize bridge = _bridge` in their @@ -564,25 +555,6 @@ - (TurboModuleHolder *)_getOrCreateTurboModuleHolder:(const char *)moduleName } } - /** - * Attach the RCTViewRegistry to this TurboModule, which allows this TurboModule - * To query a React component's UIView, given its reactTag. - * - * Usage: In the NativeModule @implementation, include: - * `@synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED` - */ - if ([module respondsToSelector:@selector(viewRegistry_DEPRECATED)] && _viewRegistry_DEPRECATED) { - @try { - [(id)module setValue:_viewRegistry_DEPRECATED forKey:@"viewRegistry_DEPRECATED"]; - } @catch (NSException *exception) { - RCTLogError( - @"%@ has no setter or ivar for its module registry, which is not " - "permitted. You must either @synthesize the viewRegistry_DEPRECATED property, " - "or provide your own setter method.", - RCTBridgeModuleNameForClass([module class])); - } - } - /** * Some modules need their own queues, but don't provide any, so we need to create it for them. * These modules typically have the following: @@ -627,6 +599,20 @@ - (TurboModuleHolder *)_getOrCreateTurboModuleHolder:(const char *)moduleName } } + /** + * Decorate TurboModules with bridgeless-compatible APIs that call into the bridge. + */ + if (_bridge) { + [_bridge attachBridgeAPIsToTurboModule:module]; + } + + /** + * If the TurboModule conforms to RCTInitializing, invoke its initialize method. + */ + if ([module respondsToSelector:@selector(initialize)]) { + [(id)module initialize]; + } + /** * Attach method queue to id object. * This is necessary because the id object can be eagerly created/initialized before the method @@ -646,7 +632,9 @@ - (TurboModuleHolder *)_getOrCreateTurboModuleHolder:(const char *)moduleName RCTModuleData *data = [[RCTModuleData alloc] initWithModuleInstance:(id)module bridge:_bridge moduleRegistry:_moduleRegistry - viewRegistry_DEPRECATED:_viewRegistry_DEPRECATED]; + viewRegistry_DEPRECATED:nil + bundleManager:nil + callableJSModules:nil]; [_bridge registerModuleForFrameUpdates:(id)module withModuleData:data]; } @@ -834,6 +822,27 @@ - (void)bridgeWillInvalidateModules:(NSNotification *)notification return; } + [self _enterInvalidatingState]; +} + +- (void)bridgeDidInvalidateModules:(NSNotification *)notification +{ + RCTBridge *bridge = notification.userInfo[@"bridge"]; + if (bridge != _bridge) { + return; + } + + [self _invalidateModules]; +} + +- (void)invalidate +{ + [self _enterInvalidatingState]; + [self _invalidateModules]; +} + +- (void)_enterInvalidatingState +{ // This should halt all insertions into _turboModuleHolders if (RCTTurboModuleSharedMutexInitEnabled()) { std::unique_lock guard(_turboModuleHoldersSharedMutex); @@ -844,13 +853,8 @@ - (void)bridgeWillInvalidateModules:(NSNotification *)notification } } -- (void)bridgeDidInvalidateModules:(NSNotification *)notification +- (void)_invalidateModules { - RCTBridge *bridge = notification.userInfo[@"bridge"]; - if (bridge != _bridge) { - return; - } - // Backward-compatibility: RCTInvalidating handling. dispatch_group_t moduleInvalidationGroup = dispatch_group_create(); @@ -868,20 +872,31 @@ - (void)bridgeDidInvalidateModules:(NSNotification *)notification shouldPerfLog:NO]; if ([module respondsToSelector:@selector(invalidate)]) { - if ([module respondsToSelector:@selector(methodQueue)]) { - dispatch_queue_t methodQueue = [module performSelector:@selector(methodQueue)]; - if (methodQueue) { - dispatch_group_enter(moduleInvalidationGroup); - [bridge - dispatchBlock:^{ - [((id)module) invalidate]; - dispatch_group_leave(moduleInvalidationGroup); - } - queue:methodQueue]; - continue; + dispatch_queue_t methodQueue = (dispatch_queue_t)objc_getAssociatedObject(module, &kAssociatedMethodQueueKey); + + if (methodQueue == nil) { + RCTLogError( + @"TurboModuleManager: Couldn't invalidate TurboModule \"%@\", because its method queue is nil.", + [module class]); + continue; + } + + dispatch_group_enter(moduleInvalidationGroup); + dispatch_block_t invalidateModule = ^{ + [((id)module) invalidate]; + dispatch_group_leave(moduleInvalidationGroup); + }; + + if (_bridge) { + [_bridge dispatchBlock:invalidateModule queue:methodQueue]; + } else { + // Bridgeless mode + if (methodQueue == RCTJSThread) { + invalidateModule(); + } else { + dispatch_async(methodQueue, invalidateModule); } } - [((id)module) invalidate]; } } @@ -893,26 +908,4 @@ - (void)bridgeDidInvalidateModules:(NSNotification *)notification _turboModuleCache.clear(); } -- (void)invalidate -{ - if (RCTTurboModuleSharedMutexInitEnabled()) { - std::unique_lock guard(_turboModuleHoldersSharedMutex); - _invalidating = true; - } else { - std::lock_guard guard(_turboModuleHoldersMutex); - _invalidating = true; - } - - // Backward-compatibility: RCTInvalidating handling, but not adhering to desired methodQueue. - for (const auto &p : _turboModuleHolders) { - id module = p.second.getModule(); - if ([module respondsToSelector:@selector(invalidate)]) { - [((id)module) invalidate]; - } - } - - _turboModuleHolders.clear(); - _turboModuleCache.clear(); -} - @end diff --git a/ReactCommon/react/nativemodule/samples/platform/ios/RCTSampleTurboModule.mm b/ReactCommon/react/nativemodule/samples/platform/ios/RCTSampleTurboModule.mm index ac1d236ed7dc2d..fc742b492fa6a6 100644 --- a/ReactCommon/react/nativemodule/samples/platform/ios/RCTSampleTurboModule.mm +++ b/ReactCommon/react/nativemodule/samples/platform/ios/RCTSampleTurboModule.mm @@ -17,8 +17,6 @@ @implementation RCTSampleTurboModule // Backward-compatible export RCT_EXPORT_MODULE() -@synthesize turboModuleRegistry = _turboModuleRegistry; - // Backward-compatible queue configuration + (BOOL)requiresMainQueueSetup { diff --git a/ReactCommon/react/renderer/animations/BUCK b/ReactCommon/react/renderer/animations/BUCK index a90d9eda97c072..fbf1c6c61393e3 100644 --- a/ReactCommon/react/renderer/animations/BUCK +++ b/ReactCommon/react/renderer/animations/BUCK @@ -91,6 +91,7 @@ fb_xplat_cxx_test( react_native_xplat_target("react/renderer/components/root:root"), react_native_xplat_target("react/renderer/components/scrollview:scrollview"), react_native_xplat_target("react/renderer/components/view:view"), + react_native_xplat_target("react/test_utils:test_utils"), "//xplat/js/react-native-github:generated_components-rncore", ], ) diff --git a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp index 3e39886dae9c06..6d8d229fa8c517 100644 --- a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp +++ b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp @@ -307,14 +307,14 @@ void LayoutAnimationKeyFrameManager::uiManagerDidConfigureNextLayoutAnimation( if (layoutAnimationConfig) { std::lock_guard lock(currentAnimationMutex_); - currentAnimation_ = better::optional{LayoutAnimation{ + uiManagerDidConfigureNextLayoutAnimation(LayoutAnimation{ -1, 0, false, *layoutAnimationConfig, successCallback, failureCallback, - {}}}; + {}}); } else { LOG(ERROR) << "Parsing LayoutAnimationConfig failed: " << (folly::dynamic)config; @@ -323,6 +323,11 @@ void LayoutAnimationKeyFrameManager::uiManagerDidConfigureNextLayoutAnimation( } } +void LayoutAnimationKeyFrameManager::uiManagerDidConfigureNextLayoutAnimation( + LayoutAnimation layoutAnimation) const { + currentAnimation_ = better::optional{layoutAnimation}; +} + void LayoutAnimationKeyFrameManager::setLayoutAnimationStatusDelegate( LayoutAnimationStatusDelegate *delegate) const { std::lock_guard lock(layoutAnimationStatusDelegateMutex_); @@ -733,6 +738,11 @@ void LayoutAnimationKeyFrameManager::getAndEraseConflictingAnimations( } } +void LayoutAnimationKeyFrameManager::setClockNow( + std::function now) { + now_ = now; +} + better::optional LayoutAnimationKeyFrameManager::pullTransaction( SurfaceId surfaceId, @@ -740,10 +750,7 @@ LayoutAnimationKeyFrameManager::pullTransaction( TransactionTelemetry const &telemetry, ShadowViewMutationList mutations) const { // Current time in milliseconds - uint64_t now = - std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()) - .count(); + uint64_t now = now_(); bool inflightAnimationsExistInitially = !inflightAnimations_.empty(); @@ -906,7 +913,7 @@ LayoutAnimationKeyFrameManager::pullTransaction( bool haveComponentDescriptor = hasComponentDescriptorForShadowView(baselineShadowView); - bool executeMutationImmediately = false; + better::optional executeMutationImmediately{}; bool isRemoveReinserted = mutation.type == ShadowViewMutation::Type::Remove && @@ -972,7 +979,7 @@ LayoutAnimationKeyFrameManager::pullTransaction( if (isRemoveReinserted || !haveConfiguration || isReparented || mutation.type == ShadowViewMutation::Type::Create || mutation.type == ShadowViewMutation::Type::Insert) { - executeMutationImmediately = true; + executeMutationImmediately = mutation; // It is possible, especially in the case of "moves", that we have a // sequence of operations like: @@ -1007,6 +1014,36 @@ LayoutAnimationKeyFrameManager::pullTransaction( } } } + } else if (mutation.type == ShadowViewMutation::Type::Remove) { + for (auto &keyframe : keyFramesToAnimate) { + if (keyframe.tag == baselineShadowView.tag) { + // If there's already an animation queued up, followed by this + // Insert, it *must* be an Update mutation animation. Other + // sequences should not be possible. + react_native_assert( + keyframe.type == AnimationConfigurationType::Update); + + // The mutation is a "remove", so it must have a + // "oldChildShadowView" + react_native_assert(mutation.oldChildShadowView.tag > 0); + + // Those asserts don't run in prod. If there's some edge-case + // that we haven't caught yet, we'd crash in debug; make sure we + // don't mutate the prevView in prod. + // Since normally the UPDATE would have been executed first and + // now it's deferred, we need to change the `oldChildShadowView` + // that is being referenced by the REMOVE mutation. + if (keyframe.type == AnimationConfigurationType::Update && + mutation.oldChildShadowView.tag > 0) { + executeMutationImmediately = ShadowViewMutation{ + mutation.type, + mutation.parentShadowView, + keyframe.viewPrev, + {}, + mutation.index}; + } + } + } } } @@ -1282,10 +1319,10 @@ LayoutAnimationKeyFrameManager::pullTransaction( keyFramesToAnimate.push_back(keyFrame); } - if (executeMutationImmediately) { + if (executeMutationImmediately.hasValue()) { PrintMutationInstruction( - "Queue Up Animation For Immediate Execution", mutation); - immediateMutations.push_back(mutation); + "Queue Up For Immediate Execution", *executeMutationImmediately); + immediateMutations.push_back(*executeMutationImmediately); } } diff --git a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h index 5bd85db70efde0..eaad96b3abb056 100644 --- a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h +++ b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h @@ -166,24 +166,35 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate, RuntimeExecutor runtimeExecutor, LayoutAnimationStatusDelegate *delegate) : runtimeExecutor_(runtimeExecutor), - layoutAnimationStatusDelegate_(delegate) {} + layoutAnimationStatusDelegate_(delegate), + now_([]() { + return std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() + .time_since_epoch()) + .count(); + }) {} ~LayoutAnimationKeyFrameManager() {} +#pragma mark UIManagerAnimationDelegate methods + void uiManagerDidConfigureNextLayoutAnimation( jsi::Runtime &runtime, RawValue const &config, const jsi::Value &successCallbackValue, const jsi::Value &failureCallbackValue) const override; + void setComponentDescriptorRegistry(SharedComponentDescriptorRegistry const & componentDescriptorRegistry) override; // TODO: add SurfaceId to this API as well bool shouldAnimateFrame() const override; - bool shouldOverridePullTransaction() const override; - void stopSurface(SurfaceId surfaceId) override; +#pragma mark MountingOverrideDelegate methods + + bool shouldOverridePullTransaction() const override; + // This is used to "hijack" the diffing process to figure out which mutations // should be animated. The mutations returned by this function will be // executed immediately. @@ -193,6 +204,11 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate, TransactionTelemetry const &telemetry, ShadowViewMutationList mutations) const override; + // Exposed for testing. + public: + void uiManagerDidConfigureNextLayoutAnimation( + LayoutAnimation layoutAnimation) const; + // LayoutAnimationStatusDelegate - this is for the platform to get // signal when animations start and complete. Setting and resetting this // delegate is protected by a mutex; ALL method calls into this delegate are @@ -207,6 +223,9 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate, mutable std::mutex layoutAnimationStatusDelegateMutex_; mutable LayoutAnimationStatusDelegate *layoutAnimationStatusDelegate_{}; + // Function that returns current time in milliseconds + std::function now_; + void adjustImmediateMutationIndicesForDelayedMutations( SurfaceId surfaceId, ShadowViewMutation &mutation, @@ -275,6 +294,9 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate, mutable std::mutex callbackWrappersPendingMutex_; mutable std::vector> callbackWrappersPending_{}; + + public: + void setClockNow(std::function now); }; static inline bool shouldFirstComeBeforeSecondRemovesOnly( @@ -300,14 +322,6 @@ static inline bool shouldFirstComeBeforeSecondMutation( return true; } - // Update comes last, before deletes - if (rhs.type == ShadowViewMutation::Type::Update) { - return true; - } - if (lhs.type == ShadowViewMutation::Type::Update) { - return false; - } - // Remove comes before insert if (lhs.type == ShadowViewMutation::Type::Remove && rhs.type == ShadowViewMutation::Type::Insert) { diff --git a/ReactCommon/react/renderer/animations/tests/LayoutAnimationTest.cpp b/ReactCommon/react/renderer/animations/tests/LayoutAnimationTest.cpp new file mode 100644 index 00000000000000..444c18ff7fd757 --- /dev/null +++ b/ReactCommon/react/renderer/animations/tests/LayoutAnimationTest.cpp @@ -0,0 +1,536 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// Uncomment when random test blocks are uncommented below. +// #include +// #include + +#include "LayoutAnimationDriver.h" + +MockClock::time_point MockClock::time_ = {}; + +namespace facebook { +namespace react { + +static void testShadowNodeTreeLifeCycleLayoutAnimations( + uint_fast32_t seed, + int treeSize, + int repeats, + int stages, + int animation_duration, + int animation_frames, + int delay_ms_between_frames, + int delay_ms_between_stages, + int delay_ms_between_repeats, + bool commits_conflicting_mutations = false, + int final_animation_delay = 0) { + auto entropy = seed == 0 ? Entropy() : Entropy(seed); + + auto eventDispatcher = EventDispatcher::Shared{}; + auto contextContainer = std::make_shared(); + auto componentDescriptorParameters = + ComponentDescriptorParameters{eventDispatcher, contextContainer, nullptr}; + auto viewComponentDescriptor = + ViewComponentDescriptor(componentDescriptorParameters); + auto rootComponentDescriptor = + RootComponentDescriptor(componentDescriptorParameters); + auto noopEventEmitter = + std::make_shared(nullptr, -1, eventDispatcher); + + // Create a RuntimeExecutor + RuntimeExecutor runtimeExecutor = + [](std::function fn) {}; + + // Create component descriptor registry for animation driver + auto providerRegistry = + std::make_shared(); + auto componentDescriptorRegistry = + providerRegistry->createComponentDescriptorRegistry( + componentDescriptorParameters); + providerRegistry->add( + concreteComponentDescriptorProvider()); + providerRegistry->add( + concreteComponentDescriptorProvider()); + + // Create Animation Driver + auto animationDriver = + std::make_shared(runtimeExecutor, nullptr); + animationDriver->setComponentDescriptorRegistry(componentDescriptorRegistry); + + // Mock animation timers + animationDriver->setClockNow([]() { + return std::chrono::duration_cast( + MockClock::now().time_since_epoch()) + .count(); + }); + + auto allNodes = std::vector{}; + + for (int i = 0; i < repeats; i++) { + allNodes.clear(); + + int surfaceIdInt = 1; + auto surfaceId = SurfaceId(surfaceIdInt); + + auto family = rootComponentDescriptor.createFamily( + {Tag(surfaceIdInt), surfaceId, nullptr}, nullptr); + + // Creating an initial root shadow node. + auto emptyRootNode = std::const_pointer_cast( + std::static_pointer_cast( + rootComponentDescriptor.createShadowNode( + ShadowNodeFragment{RootShadowNode::defaultSharedProps()}, + family))); + + // Applying size constraints. + emptyRootNode = emptyRootNode->clone( + LayoutConstraints{ + Size{512, 0}, Size{512, std::numeric_limits::infinity()}}, + LayoutContext{}); + + // Generation of a random tree. + auto singleRootChildNode = + generateShadowNodeTree(entropy, viewComponentDescriptor, treeSize); + + // Injecting a tree into the root node. + auto currentRootNode = std::static_pointer_cast( + emptyRootNode->ShadowNode::clone(ShadowNodeFragment{ + ShadowNodeFragment::propsPlaceholder(), + std::make_shared( + SharedShadowNodeList{singleRootChildNode})})); + + // Building an initial view hierarchy. + auto viewTree = buildStubViewTreeWithoutUsingDifferentiator(*emptyRootNode); + viewTree.mutate( + calculateShadowViewMutations(*emptyRootNode, *currentRootNode, true)); + + for (int j = 0; j < stages; j++) { + auto nextRootNode = currentRootNode; + + // Mutating the tree. + alterShadowTree( + entropy, + nextRootNode, + { + &messWithChildren, + &messWithYogaStyles, + &messWithLayoutableOnlyFlag, + }); + + std::vector affectedLayoutableNodes{}; + affectedLayoutableNodes.reserve(1024); + + // Laying out the tree. + std::const_pointer_cast(nextRootNode) + ->layoutIfNeeded(&affectedLayoutableNodes); + + nextRootNode->sealRecursive(); + allNodes.push_back(nextRootNode); + + // Calculating mutations. + auto originalMutations = + calculateShadowViewMutations(*currentRootNode, *nextRootNode, true); + + // If tree randomization produced no changes in the form of mutations, + // don't bother trying to animate because this violates a bunch of our + // assumptions in this test + if (originalMutations.size() == 0) { + continue; + } + + // Configure animation + animationDriver->uiManagerDidConfigureNextLayoutAnimation( + {surfaceId, + 0, + false, + {(double)animation_duration, + {/* Create */ AnimationType::EaseInEaseOut, + AnimationProperty::Opacity, + (double)animation_duration, + 0, + 0, + 0}, + {/* Update */ AnimationType::EaseInEaseOut, + AnimationProperty::ScaleXY, + (double)animation_duration, + 0, + 0, + 0}, + {/* Delete */ AnimationType::EaseInEaseOut, + AnimationProperty::Opacity, + (double)animation_duration, + 0, + 0, + 0}}, + {}, + {}, + {}}); + + // Get mutations for each frame + for (int k = 0; k < animation_frames + 2; k++) { + auto mutationsInput = ShadowViewMutation::List{}; + if (k == 0) { + mutationsInput = originalMutations; + } + + if (k != (animation_frames + 1)) { + EXPECT_TRUE(animationDriver->shouldOverridePullTransaction()); + } else if (!commits_conflicting_mutations) { + EXPECT_FALSE(animationDriver->shouldOverridePullTransaction()); + } + + auto telemetry = TransactionTelemetry{}; + telemetry.willLayout(); + telemetry.willCommit(); + telemetry.willDiff(); + + auto transaction = animationDriver->pullTransaction( + surfaceId, 0, telemetry, mutationsInput); + + EXPECT_TRUE(transaction.has_value() || k == animation_frames); + + // We have something to validate. + if (transaction.has_value()) { + auto mutations = transaction->getMutations(); + + // Mutating the view tree. + viewTree.mutate(mutations); + + // We don't do any validation on this until all animations are + // finished! + } + + MockClock::advance_by( + std::chrono::milliseconds(delay_ms_between_frames)); + } + + // After the animation is completed... + // Build a view tree to compare with. + // After all the synthetic mutations, at the end of the animation, + // the mutated and newly-constructed trees should be identical. + if (!commits_conflicting_mutations) { + auto rebuiltViewTree = + buildStubViewTreeWithoutUsingDifferentiator(*nextRootNode); + + // Comparing the newly built tree with the updated one. + if (rebuiltViewTree != viewTree) { + // Something went wrong. + + LOG(ERROR) + << "Entropy seed: " << entropy.getSeed() + << ". To see why trees are different, define STUB_VIEW_TREE_VERBOSE and see logging in StubViewTree.cpp.\n"; + + EXPECT_TRUE(false); + } + } + + currentRootNode = nextRootNode; + + MockClock::advance_by(std::chrono::milliseconds(delay_ms_between_stages)); + } + + // Flush all remaining animations before validating trees + if (final_animation_delay > 0) { + MockClock::advance_by(std::chrono::milliseconds(final_animation_delay)); + + auto telemetry = TransactionTelemetry{}; + telemetry.willLayout(); + telemetry.willCommit(); + telemetry.willDiff(); + + auto transaction = + animationDriver->pullTransaction(surfaceId, 0, telemetry, {}); + // We have something to validate. + if (transaction.hasValue()) { + auto mutations = transaction->getMutations(); + + // Mutating the view tree. + viewTree.mutate(mutations); + + // We don't do any validation on this until all animations are + // finished! + } + } + + // After all animations are completed... + // Build a view tree to compare with. + // After all the synthetic mutations, at the end of the animation, + // the mutated and newly-constructed trees should be identical. + if (commits_conflicting_mutations) { + auto rebuiltViewTree = + buildStubViewTreeWithoutUsingDifferentiator(*currentRootNode); + + // Comparing the newly built tree with the updated one. + if (rebuiltViewTree != viewTree) { + // Something went wrong. + + LOG(ERROR) + << "Entropy seed: " << entropy.getSeed() + << ". To see why trees are different, define STUB_VIEW_TREE_VERBOSE and see logging in StubViewTree.cpp.\n"; + + EXPECT_TRUE(false); + } + } + + MockClock::advance_by(std::chrono::milliseconds(delay_ms_between_repeats)); + } + + SUCCEED(); +} + +} // namespace react +} // namespace facebook + +using namespace facebook::react; + +TEST( + LayoutAnimationTest, + stableSmallerTreeFewRepeatsFewStages_NonOverlapping_2029343357) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 2029343357, /* working seed found 5-10-2021 */ + /* size */ 128, + /* repeats */ 128, + /* stages */ 10, + /* animation_duration */ 1000, + /* animation_frames*/ 10, + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000); +} + +TEST( + LayoutAnimationTest, + stableSmallerTreeFewRepeatsFewStages_NonOverlapping_3619914559) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 3619914559, /* working seed found 5-10-2021 */ + /* size */ 128, + /* repeats */ 128, + /* stages */ 10, + /* animation_duration */ 1000, + /* animation_frames*/ 10, + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000); +} + +TEST( + LayoutAnimationTest, + stableSmallerTreeFewRepeatsFewStages_NonOverlapping_597132284) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 597132284, /* failing seed found 5-10-2021 */ + /* size */ 128, + /* repeats */ 128, + /* stages */ 10, + /* animation_duration */ 1000, + /* animation_frames*/ 10, + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000); +} + +TEST( + LayoutAnimationTest, + stableSmallerTreeFewRepeatsFewStages_NonOverlapping_774986518) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 774986518, /* failing seed found 5-10-2021 */ + /* size */ 128, + /* repeats */ 128, + /* stages */ 10, + /* animation_duration */ 1000, + /* animation_frames*/ 10, + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000); +} + +TEST( + LayoutAnimationTest, + stableSmallerTreeFewRepeatsFewStages_NonOverlapping_1450614414) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 1450614414, /* failing seed found 5-10-2021 */ + /* size */ 128, + /* repeats */ 128, + /* stages */ 10, + /* animation_duration */ 1000, + /* animation_frames*/ 10, + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000); +} + +TEST(LayoutAnimationTest, stableBiggerTreeFewRepeatsFewStages_NonOverlapping) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 2029343357, + /* size */ 512, + /* repeats */ 32, + /* stages */ 10, + /* animation_duration */ 1000, + /* animation_frames*/ 10, + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000); +} + +TEST(LayoutAnimationTest, stableBiggerTreeFewRepeatsManyStages_NonOverlapping) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 2029343357, + /* size */ 512, + /* repeats */ 32, + /* stages */ 128, + /* animation_duration */ 1000, + /* animation_frames*/ 10, + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000); +} + +// You may uncomment this - locally only! - to generate failing seeds. +// TEST(LayoutAnimationTest, stableSmallerTreeFewRepeatsFewStages_Random) { +// std::random_device device; +// for (int i = 0; i < 10; i++) { +// uint_fast32_t seed = device(); +// LOG(ERROR) << "Seed: " << seed; +// testShadowNodeTreeLifeCycleLayoutAnimations( +// /* seed */ seed, +// /* size */ 128, +// /* repeats */ 128, +// /* stages */ 10, +// /* animation_duration */ 1000, +// /* animation_frames*/ 10, +// /* delay_ms_between_frames */ 100, +// /* delay_ms_between_stages */ 100, +// /* delay_ms_between_repeats */ 2000); +// } +// // Fail if you want output to get seeds +// LOG(ERROR) << "ALL RUNS SUCCESSFUL"; +// // react_native_assert(false); +// } + +// +// These tests are "overlapping", meaning that mutations will be committed +// before the previous animation completes. +// + +TEST( + LayoutAnimationTest, + stableSmallerTreeFewRepeatsFewStages_Overlapping_2029343357) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 2029343357, + /* size */ 128, + /* repeats */ 128, + /* stages */ 10, + /* animation_duration */ 1000, + /* animation_frames*/ 9, // an animation completes in 10 frames, so this + // causes conflicts + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000, + /* commits_conflicting_mutations */ true, + /* final_animation_delay */ 10000 + 1); +} + +TEST( + LayoutAnimationTest, + stableSmallerTreeFewRepeatsFewStages_Overlapping_597132284) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 597132284, + /* size */ 128, + /* repeats */ 128, + /* stages */ 10, + /* animation_duration */ 1000, + /* animation_frames*/ 9, // an animation completes in 10 frames, so this + // causes conflicts + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000, + /* commits_conflicting_mutations */ true, + /* final_animation_delay */ 10000 + 1); +} + +TEST( + LayoutAnimationTest, + stableSmallerTreeFewRepeatsFewStages_Overlapping_ManyConflicts_597132284) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 597132284, + /* size */ 128, + /* repeats */ 128, + /* stages */ 50, + /* animation_duration */ 1000, + /* animation_frames*/ 5, // an animation completes in 10 frames, so this + // causes conflicts. We only animate 5 frames, + // but have 50 stages, so conflicts stack up + // quickly. + /* delay_ms_between_frames */ 100, + /* delay_ms_between_stages */ 100, + /* delay_ms_between_repeats */ 2000, + /* commits_conflicting_mutations */ true, + /* final_animation_delay */ 50000 + 1); +} + +TEST( + LayoutAnimationTest, + stableBiggerTreeFewRepeatsManyStages_Overlapping_ManyConflicts_2029343357) { + testShadowNodeTreeLifeCycleLayoutAnimations( + /* seed */ 2029343357, + /* size */ 512, + /* repeats */ 32, + /* stages */ 128, + /* animation_duration */ 1000, + /* animation_frames*/ 10, + /* delay_ms_between_frames */ 10, + /* delay_ms_between_stages */ 10, + /* delay_ms_between_repeats */ 2000, + /* commits_conflicting_mutations */ true, + /* final_animation_delay */ (128 * 1000 + 100)); +} + +// You may uncomment this - +// locally only !-to generate failing seeds. +// TEST( +// LayoutAnimationTest, +// stableSmallerTreeFewRepeatsFewStages_Overlapping_Random) { +// std::random_device device; +// for (int i = 0; i < 10; i++) { +// uint_fast32_t seed = device(); +// LOG(ERROR) << "Seed: " << seed; +// testShadowNodeTreeLifeCycleLayoutAnimations( +// /* seed */ seed, +// /* size */ 512, +// /* repeats */ 32, +// /* stages */ 128, +// /* animation_duration */ 1000, +// /* animation_frames*/ 10, +// /* delay_ms_between_frames */ 10, +// /* delay_ms_between_stages */ 10, +// /* delay_ms_between_repeats */ 2000, +// /* commits_conflicting_mutations */ true, +// /* final_animation_delay */ (128 * 1000 + 100)); +// } +// // Fail if you want output to get seeds +// LOG(ERROR) << "ALL RUNS SUCCESSFUL"; +// // react_native_assert(false); +// } diff --git a/ReactCommon/react/renderer/components/root/BUCK b/ReactCommon/react/renderer/components/root/BUCK index 79c5a11420984c..b09dc8c12d1197 100644 --- a/ReactCommon/react/renderer/components/root/BUCK +++ b/ReactCommon/react/renderer/components/root/BUCK @@ -76,5 +76,6 @@ fb_xplat_cxx_test( ":root", "//xplat/folly:molly", "//xplat/third-party/gmock:gtest", + react_native_xplat_target("react/renderer/element:element"), ], ) diff --git a/ReactCommon/react/renderer/components/root/RootShadowNode.cpp b/ReactCommon/react/renderer/components/root/RootShadowNode.cpp index 099be0d0b38c1a..eeeb0c5ac68f60 100644 --- a/ReactCommon/react/renderer/components/root/RootShadowNode.cpp +++ b/ReactCommon/react/renderer/components/root/RootShadowNode.cpp @@ -48,6 +48,11 @@ RootShadowNode::Unshared RootShadowNode::clone( ShadowNodeFragment{ /* .props = */ props, }); + + if (layoutConstraints != getConcreteProps().layoutConstraints) { + newRootShadowNode->dirtyLayout(); + } + return newRootShadowNode; } diff --git a/ReactCommon/react/renderer/components/root/tests/RootShadowNodeTest.cpp b/ReactCommon/react/renderer/components/root/tests/RootShadowNodeTest.cpp index 964411c92b57ba..f0553e7b99c653 100644 --- a/ReactCommon/react/renderer/components/root/tests/RootShadowNodeTest.cpp +++ b/ReactCommon/react/renderer/components/root/tests/RootShadowNodeTest.cpp @@ -5,10 +5,38 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include +#include +#include +#include #include -TEST(RootShadowNodeTest, testSomething) { - // TODO +namespace facebook::react { + +TEST(RootShadowNodeTest, cloneWithLayoutConstraints) { + auto builder = simpleComponentBuilder(); + std::shared_ptr rootShadowNode; + LayoutConstraints defaultLayoutConstraints = {}; + + auto element = + Element().reference(rootShadowNode).tag(1).props([&] { + auto sharedProps = std::make_shared(); + sharedProps->layoutConstraints = defaultLayoutConstraints; + return sharedProps; + }); + + builder.build(element); + + EXPECT_FALSE(rootShadowNode->getIsLayoutClean()); + EXPECT_TRUE(rootShadowNode->layoutIfNeeded()); + EXPECT_TRUE(rootShadowNode->getIsLayoutClean()); + + auto clonedWithDiffentLayoutConstraints = + rootShadowNode->clone(LayoutConstraints{{0, 0}, {10, 10}}, {}); + + EXPECT_FALSE(clonedWithDiffentLayoutConstraints->getIsLayoutClean()); + EXPECT_TRUE(clonedWithDiffentLayoutConstraints->layoutIfNeeded()); } + +} // namespace facebook::react diff --git a/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h b/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h index 09336eec7569b5..74ea1045f0d952 100644 --- a/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h +++ b/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h @@ -28,12 +28,12 @@ class ScrollViewProps final : public ViewProps { bool canCancelContentTouches{true}; bool centerContent{}; bool automaticallyAdjustContentInsets{}; - Float decelerationRate{0.998}; + Float decelerationRate{0.998f}; bool directionalLockEnabled{}; ScrollViewIndicatorStyle indicatorStyle{}; ScrollViewKeyboardDismissMode keyboardDismissMode{}; - Float maximumZoomScale{1.0}; - Float minimumZoomScale{1.0}; + Float maximumZoomScale{1.0f}; + Float minimumZoomScale{1.0f}; bool scrollEnabled{true}; bool pagingEnabled{}; bool pinchGestureEnabled{true}; @@ -41,7 +41,7 @@ class ScrollViewProps final : public ViewProps { bool showsHorizontalScrollIndicator{true}; bool showsVerticalScrollIndicator{true}; Float scrollEventThrottle{}; - Float zoomScale{1.0}; + Float zoomScale{1.0f}; EdgeInsets contentInset{}; Point contentOffset{}; EdgeInsets scrollIndicatorInsets{}; diff --git a/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp b/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp index e5faef33faff8a..09c860740f3224 100644 --- a/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp +++ b/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.cpp @@ -34,7 +34,7 @@ void ScrollViewShadowNode::updateStateIfNeeded() { void ScrollViewShadowNode::updateScrollContentOffsetIfNeeded() { #ifndef ANDROID if (getLayoutMetrics().layoutDirection == LayoutDirection::RightToLeft) { - // Yoga place `contentView` on the right side of `scrollView` when RTL + // Yoga places `contentView` on the right side of `scrollView` when RTL // layout is enforced. To correct for this, in RTL setting, correct the // frame's origin. React Native Classic does this as well in // `RCTScrollContentShadowView.m`. @@ -58,8 +58,9 @@ void ScrollViewShadowNode::layout(LayoutContext layoutContext) { } Point ScrollViewShadowNode::getContentOriginOffset() const { - auto contentOffset = getStateData().contentOffset; - return {-contentOffset.x, -contentOffset.y}; + auto stateData = getStateData(); + auto contentOffset = stateData.contentOffset; + return {-contentOffset.x, -contentOffset.y + stateData.scrollAwayPaddingTop}; } } // namespace react diff --git a/ReactCommon/react/renderer/components/scrollview/ScrollViewState.h b/ReactCommon/react/renderer/components/scrollview/ScrollViewState.h index 3f979ab3f597b9..6d3dd7e632525f 100644 --- a/ReactCommon/react/renderer/components/scrollview/ScrollViewState.h +++ b/ReactCommon/react/renderer/components/scrollview/ScrollViewState.h @@ -25,6 +25,7 @@ class ScrollViewState final { public: Point contentOffset; Rect contentBoundingRect; + int scrollAwayPaddingTop; /* * Returns size of scrollable area. @@ -37,11 +38,13 @@ class ScrollViewState final { : contentOffset( {(Float)data["contentOffsetLeft"].getDouble(), (Float)data["contentOffsetTop"].getDouble()}), - contentBoundingRect({}){}; + contentBoundingRect({}), + scrollAwayPaddingTop((Float)data["scrollAwayPaddingTop"].getDouble()){}; folly::dynamic getDynamic() const { return folly::dynamic::object("contentOffsetLeft", contentOffset.x)( - "contentOffsetTop", contentOffset.y); + "contentOffsetTop", contentOffset.y)( + "scrollAwayPaddingTop", scrollAwayPaddingTop); }; MapBuffer getMapBuffer() const { return MapBufferBuilder::EMPTY(); diff --git a/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp b/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp index 09da2f41760a89..46f4098784165c 100644 --- a/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp +++ b/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp @@ -78,8 +78,8 @@ Content ParagraphShadowNode::getContentWithMeasuredAttachments( laytableShadowNode->measure(layoutContext, localLayoutConstraints); // Rounding to *next* value on the pixel grid. - size.width += 0.01; - size.height += 0.01; + size.width += 0.01f; + size.height += 0.01f; size = roundToPixel<&ceil>(size, layoutContext.pointScaleFactor); auto fragmentLayoutMetrics = LayoutMetrics{}; @@ -186,7 +186,7 @@ void ParagraphShadowNode::layout(LayoutContext layoutContext) { react_native_assert( content.attachments.size() == measurement.attachments.size()); - for (auto i = 0; i < content.attachments.size(); i++) { + for (size_t i = 0; i < content.attachments.size(); i++) { auto &attachment = content.attachments.at(i); if (!traitCast(attachment.shadowNode)) { diff --git a/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputEventEmitter.cpp b/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputEventEmitter.cpp index 6342a6c1ff239a..8d4284771d2900 100644 --- a/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputEventEmitter.cpp +++ b/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputEventEmitter.cpp @@ -72,7 +72,8 @@ void TextInputEventEmitter::onBlur( void TextInputEventEmitter::onChange( TextInputMetrics const &textInputMetrics) const { - dispatchTextInputEvent("change", textInputMetrics); + dispatchTextInputEvent( + "change", textInputMetrics, EventPriority::SynchronousUnbatched); } void TextInputEventEmitter::onChangeText( diff --git a/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h b/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h index 157aebed39bca4..b9306c2967d49a 100644 --- a/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h +++ b/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h @@ -7,7 +7,9 @@ #pragma once +#include #include +#include namespace facebook { namespace react { @@ -45,6 +47,11 @@ constexpr enum AccessibilityTraits operator&( return (enum AccessibilityTraits)((uint32_t)lhs & (uint32_t)rhs); } +struct AccessibilityAction { + std::string name{""}; + better::optional label{}; +}; + struct AccessibilityState { bool disabled{false}; bool selected{false}; diff --git a/ReactCommon/react/renderer/components/view/AccessibilityProps.h b/ReactCommon/react/renderer/components/view/AccessibilityProps.h index 4235e7cdd6c4f8..362ee83f08546b 100644 --- a/ReactCommon/react/renderer/components/view/AccessibilityProps.h +++ b/ReactCommon/react/renderer/components/view/AccessibilityProps.h @@ -29,7 +29,7 @@ class AccessibilityProps { AccessibilityState accessibilityState; std::string accessibilityLabel{""}; std::string accessibilityHint{""}; - std::vector accessibilityActions{}; + std::vector accessibilityActions{}; bool accessibilityViewIsModal{false}; bool accessibilityElementsHidden{false}; bool accessibilityIgnoresInvertColors{false}; diff --git a/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp b/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp index c02b1c3bcc784e..1d8ed3e330409f 100644 --- a/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp +++ b/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp @@ -62,17 +62,23 @@ static jsi::Value touchEventPayload( void TouchEventEmitter::dispatchTouchEvent( std::string const &type, TouchEvent const &event, - EventPriority const &priority) const { + EventPriority priority, + RawEvent::Category category) const { dispatchEvent( type, [event](jsi::Runtime &runtime) { return touchEventPayload(runtime, event); }, - priority); + priority, + category); } void TouchEventEmitter::onTouchStart(TouchEvent const &event) const { - dispatchTouchEvent("touchStart", event, EventPriority::AsynchronousBatched); + dispatchTouchEvent( + "touchStart", + event, + EventPriority::AsynchronousBatched, + RawEvent::Category::ContinuousStart); } void TouchEventEmitter::onTouchMove(TouchEvent const &event) const { @@ -82,11 +88,19 @@ void TouchEventEmitter::onTouchMove(TouchEvent const &event) const { } void TouchEventEmitter::onTouchEnd(TouchEvent const &event) const { - dispatchTouchEvent("touchEnd", event, EventPriority::AsynchronousBatched); + dispatchTouchEvent( + "touchEnd", + event, + EventPriority::AsynchronousBatched, + RawEvent::Category::ContinuousEnd); } void TouchEventEmitter::onTouchCancel(TouchEvent const &event) const { - dispatchTouchEvent("touchCancel", event, EventPriority::AsynchronousBatched); + dispatchTouchEvent( + "touchCancel", + event, + EventPriority::AsynchronousBatched, + RawEvent::Category::ContinuousEnd); } } // namespace react diff --git a/ReactCommon/react/renderer/components/view/TouchEventEmitter.h b/ReactCommon/react/renderer/components/view/TouchEventEmitter.h index 54a29049039994..c225fbb9d6394b 100644 --- a/ReactCommon/react/renderer/components/view/TouchEventEmitter.h +++ b/ReactCommon/react/renderer/components/view/TouchEventEmitter.h @@ -33,7 +33,8 @@ class TouchEventEmitter : public EventEmitter { void dispatchTouchEvent( std::string const &type, TouchEvent const &event, - EventPriority const &priority) const; + EventPriority priority, + RawEvent::Category category) const; }; } // namespace react diff --git a/ReactCommon/react/renderer/components/view/ViewEventEmitter.cpp b/ReactCommon/react/renderer/components/view/ViewEventEmitter.cpp index 04902b3bedfa8c..f978934cc239ba 100644 --- a/ReactCommon/react/renderer/components/view/ViewEventEmitter.cpp +++ b/ReactCommon/react/renderer/components/view/ViewEventEmitter.cpp @@ -15,7 +15,7 @@ namespace react { void ViewEventEmitter::onAccessibilityAction(const std::string &name) const { dispatchEvent("accessibilityAction", [name](jsi::Runtime &runtime) { auto payload = jsi::Object(runtime); - payload.setProperty(runtime, "action", name); + payload.setProperty(runtime, "actionName", name); return payload; }); } diff --git a/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp b/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp index 1dcbb084b3a4e2..029c3eaf8fc0c9 100644 --- a/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp +++ b/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp @@ -28,14 +28,6 @@ ViewShadowNode::ViewShadowNode( initialize(); } -static bool isColorMeaningful(SharedColor const &color) noexcept { - if (!color) { - return false; - } - - return colorComponentsFromColor(color).alpha > 0; -} - void ViewShadowNode::initialize() noexcept { auto &viewProps = static_cast(*props_); diff --git a/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h b/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h index a2ed220ce990cb..5eb0b6e4a4df4b 100644 --- a/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h +++ b/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h @@ -21,7 +21,7 @@ inline void fromString(const std::string &string, AccessibilityTraits &result) { result = AccessibilityTraits::None; return; } - if (string == "button") { + if (string == "button" || string == "togglebutton") { result = AccessibilityTraits::Button; return; } @@ -192,5 +192,22 @@ inline void fromRawValue( } } +inline void fromRawValue(const RawValue &value, AccessibilityAction &result) { + auto map = (better::map)value; + + auto name = map.find("name"); + react_native_assert(name != map.end() && name->second.hasType()); + if (name != map.end()) { + fromRawValue(name->second, result.name); + } + + auto label = map.find("label"); + if (label != map.end()) { + if (label->second.hasType()) { + result.label = (std::string)label->second; + } + } +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/react/renderer/components/view/primitives.h b/ReactCommon/react/renderer/components/view/primitives.h index f50f37e71fa9e3..52e5f3f08c218f 100644 --- a/ReactCommon/react/renderer/components/view/primitives.h +++ b/ReactCommon/react/renderer/components/view/primitives.h @@ -38,18 +38,19 @@ struct CascadedRectangleEdges { OptionalT all{}; Counterpart resolve(bool isRTL, T defaults) const { - const auto leading = isRTL ? end : start; - const auto trailing = isRTL ? start : end; + const auto leadingEdge = isRTL ? end : start; + const auto trailingEdge = isRTL ? start : end; const auto horizontalOrAllOrDefault = horizontal.value_or(all.value_or(defaults)); const auto verticalOrAllOrDefault = vertical.value_or(all.value_or(defaults)); return { - /* .left = */ left.value_or(leading.value_or(horizontalOrAllOrDefault)), + /* .left = */ + left.value_or(leadingEdge.value_or(horizontalOrAllOrDefault)), /* .top = */ top.value_or(verticalOrAllOrDefault), /* .right = */ - right.value_or(trailing.value_or(horizontalOrAllOrDefault)), + right.value_or(trailingEdge.value_or(horizontalOrAllOrDefault)), /* .bottom = */ bottom.value_or(verticalOrAllOrDefault), }; } diff --git a/ReactCommon/react/renderer/core/BUCK b/ReactCommon/react/renderer/core/BUCK index 0888f5e42a7ef5..8ed779f4283679 100644 --- a/ReactCommon/react/renderer/core/BUCK +++ b/ReactCommon/react/renderer/core/BUCK @@ -87,6 +87,7 @@ fb_xplat_cxx_test( "//xplat/third-party/gmock:gtest", react_native_xplat_target("react/renderer/components/view:view"), ":core", + "//xplat/hermes/API:HermesAPI", ], ) diff --git a/ReactCommon/react/renderer/core/BatchedEventQueue.cpp b/ReactCommon/react/renderer/core/BatchedEventQueue.cpp index 1c363a64c65d58..64d8df3288ce72 100644 --- a/ReactCommon/react/renderer/core/BatchedEventQueue.cpp +++ b/ReactCommon/react/renderer/core/BatchedEventQueue.cpp @@ -11,44 +11,12 @@ namespace facebook { namespace react { BatchedEventQueue::BatchedEventQueue( - EventPipe eventPipe, - StatePipe statePipe, + EventQueueProcessor eventProcessor, std::unique_ptr eventBeat) - : EventQueue(eventPipe, statePipe, std::move(eventBeat)) {} + : EventQueue(std::move(eventProcessor), std::move(eventBeat)) {} void BatchedEventQueue::onEnqueue() const { eventBeat_->request(); } - -void BatchedEventQueue::enqueueUniqueEvent(RawEvent const &rawEvent) const { - { - std::lock_guard lock(queueMutex_); - - auto repeatedEvent = eventQueue_.rend(); - - for (auto it = eventQueue_.rbegin(); it != eventQueue_.rend(); ++it) { - if (it->type == rawEvent.type && - it->eventTarget == rawEvent.eventTarget) { - repeatedEvent = it; - break; - } else if (it->eventTarget == rawEvent.eventTarget) { - // It is necessary to maintain order of different event types - // for the same target. If the same target has event types A1, B1 - // in the event queue and event A2 occurs. A1 has to stay in the - // queue. - break; - } - } - - if (repeatedEvent == eventQueue_.rend()) { - eventQueue_.push_back(rawEvent); - } else { - *repeatedEvent = std::move(rawEvent); - } - } - - onEnqueue(); -} - } // namespace react } // namespace facebook diff --git a/ReactCommon/react/renderer/core/BatchedEventQueue.h b/ReactCommon/react/renderer/core/BatchedEventQueue.h index 827ef87886ef4a..ea18dcf3d928b6 100644 --- a/ReactCommon/react/renderer/core/BatchedEventQueue.h +++ b/ReactCommon/react/renderer/core/BatchedEventQueue.h @@ -8,6 +8,7 @@ #pragma once #include +#include namespace facebook { namespace react { @@ -19,18 +20,10 @@ namespace react { class BatchedEventQueue final : public EventQueue { public: BatchedEventQueue( - EventPipe eventPipe, - StatePipe statePipe, + EventQueueProcessor eventProcessor, std::unique_ptr eventBeat); void onEnqueue() const override; - - /* - * Enqueues and (probably later) dispatches a given event. - * Deletes last RawEvent from the queue if it has the same type and target. - * Can be called on any thread. - */ - void enqueueUniqueEvent(const RawEvent &rawEvent) const; }; } // namespace react diff --git a/ReactCommon/react/renderer/core/EventDispatcher.cpp b/ReactCommon/react/renderer/core/EventDispatcher.cpp index 8ece2ab3a07aff..849ac218fd9321 100644 --- a/ReactCommon/react/renderer/core/EventDispatcher.cpp +++ b/ReactCommon/react/renderer/core/EventDispatcher.cpp @@ -17,31 +17,27 @@ namespace facebook { namespace react { EventDispatcher::EventDispatcher( - EventPipe const &eventPipe, - StatePipe const &statePipe, + EventQueueProcessor eventProcessor, EventBeat::Factory const &synchonousEventBeatFactory, EventBeat::Factory const &asynchonousEventBeatFactory, - EventBeat::SharedOwnerBox const &ownerBox) + EventBeat::SharedOwnerBox const &ownerBox, + bool unbatchedQueuesOnly) : synchronousUnbatchedQueue_(std::make_unique( - eventPipe, - statePipe, + eventProcessor, synchonousEventBeatFactory(ownerBox))), synchronousBatchedQueue_(std::make_unique( - eventPipe, - statePipe, + eventProcessor, synchonousEventBeatFactory(ownerBox))), asynchronousUnbatchedQueue_(std::make_unique( - eventPipe, - statePipe, + eventProcessor, asynchonousEventBeatFactory(ownerBox))), asynchronousBatchedQueue_(std::make_unique( - eventPipe, - statePipe, - asynchonousEventBeatFactory(ownerBox))) {} + eventProcessor, + asynchonousEventBeatFactory(ownerBox))), + unbatchedQueuesOnly_(unbatchedQueuesOnly) {} -void EventDispatcher::dispatchEvent( - RawEvent const &rawEvent, - EventPriority priority) const { +void EventDispatcher::dispatchEvent(RawEvent &&rawEvent, EventPriority priority) + const { getEventQueue(priority).enqueueEvent(std::move(rawEvent)); } @@ -51,20 +47,37 @@ void EventDispatcher::dispatchStateUpdate( getEventQueue(priority).enqueueStateUpdate(std::move(stateUpdate)); } -void EventDispatcher::dispatchUniqueEvent(RawEvent const &rawEvent) const { - asynchronousBatchedQueue_->enqueueUniqueEvent(rawEvent); +void EventDispatcher::dispatchUniqueEvent(RawEvent &&rawEvent) const { + if (unbatchedQueuesOnly_) { + asynchronousUnbatchedQueue_->enqueueUniqueEvent(std::move(rawEvent)); + } else { + asynchronousBatchedQueue_->enqueueUniqueEvent(std::move(rawEvent)); + } } const EventQueue &EventDispatcher::getEventQueue(EventPriority priority) const { - switch (priority) { - case EventPriority::SynchronousUnbatched: - return *synchronousUnbatchedQueue_; - case EventPriority::SynchronousBatched: - return *synchronousBatchedQueue_; - case EventPriority::AsynchronousUnbatched: - return *asynchronousUnbatchedQueue_; - case EventPriority::AsynchronousBatched: - return *asynchronousBatchedQueue_; + if (unbatchedQueuesOnly_) { + switch (priority) { + case EventPriority::SynchronousUnbatched: + return *synchronousUnbatchedQueue_; + case EventPriority::SynchronousBatched: + return *synchronousUnbatchedQueue_; + case EventPriority::AsynchronousUnbatched: + return *asynchronousUnbatchedQueue_; + case EventPriority::AsynchronousBatched: + return *asynchronousUnbatchedQueue_; + } + } else { + switch (priority) { + case EventPriority::SynchronousUnbatched: + return *synchronousUnbatchedQueue_; + case EventPriority::SynchronousBatched: + return *synchronousBatchedQueue_; + case EventPriority::AsynchronousUnbatched: + return *asynchronousUnbatchedQueue_; + case EventPriority::AsynchronousBatched: + return *asynchronousBatchedQueue_; + } } } diff --git a/ReactCommon/react/renderer/core/EventDispatcher.h b/ReactCommon/react/renderer/core/EventDispatcher.h index d3fb37c132754f..c858201684920d 100644 --- a/ReactCommon/react/renderer/core/EventDispatcher.h +++ b/ReactCommon/react/renderer/core/EventDispatcher.h @@ -7,21 +7,17 @@ #pragma once -#include -#include - #include #include -#include #include -#include +#include #include #include namespace facebook { namespace react { -class RawEvent; +struct RawEvent; /* * Represents event-delivery infrastructure. @@ -33,23 +29,23 @@ class EventDispatcher { using Weak = std::weak_ptr; EventDispatcher( - EventPipe const &eventPipe, - StatePipe const &statePipe, + EventQueueProcessor eventProcessor, EventBeat::Factory const &synchonousEventBeatFactory, EventBeat::Factory const &asynchonousEventBeatFactory, - EventBeat::SharedOwnerBox const &ownerBox); + EventBeat::SharedOwnerBox const &ownerBox, + bool unbatchedQueuesOnly); /* * Dispatches a raw event with given priority using event-delivery pipe. */ - void dispatchEvent(RawEvent const &rawEvent, EventPriority priority) const; + void dispatchEvent(RawEvent &&rawEvent, EventPriority priority) const; /* * Dispatches a raw event with asynchronous batched priority. Before the * dispatch we make sure that no other RawEvent of same type and same target * is on the queue. */ - void dispatchUniqueEvent(RawEvent const &rawEvent) const; + void dispatchUniqueEvent(RawEvent &&rawEvent) const; /* * Dispatches a state update with given priority. @@ -64,6 +60,8 @@ class EventDispatcher { std::unique_ptr synchronousBatchedQueue_; std::unique_ptr asynchronousUnbatchedQueue_; std::unique_ptr asynchronousBatchedQueue_; + + bool const unbatchedQueuesOnly_; }; } // namespace react diff --git a/ReactCommon/react/renderer/core/EventEmitter.cpp b/ReactCommon/react/renderer/core/EventEmitter.cpp index 54a0c8154b2acb..f1752192ce7b69 100644 --- a/ReactCommon/react/renderer/core/EventEmitter.cpp +++ b/ReactCommon/react/renderer/core/EventEmitter.cpp @@ -26,7 +26,7 @@ static std::string normalizeEventType(const std::string &type) { auto prefixedType = type; if (type.find("top", 0) != 0) { prefixedType.insert(0, "top"); - prefixedType[3] = toupper(prefixedType[3]); + prefixedType[3] = static_cast(toupper(prefixedType[3])); } return prefixedType; } @@ -52,19 +52,25 @@ EventEmitter::EventEmitter( void EventEmitter::dispatchEvent( const std::string &type, const folly::dynamic &payload, - const EventPriority &priority) const { - dispatchEvent( - type, - [payload](jsi::Runtime &runtime) { - return valueFromDynamic(runtime, payload); - }, - priority); + EventPriority priority) const { + dispatchEvent(type, [payload](jsi::Runtime &runtime) { + return valueFromDynamic(runtime, payload); + }); +} + +void EventEmitter::dispatchUniqueEvent( + const std::string &type, + const folly::dynamic &payload) const { + dispatchUniqueEvent(type, [payload](jsi::Runtime &runtime) { + return valueFromDynamic(runtime, payload); + }); } void EventEmitter::dispatchEvent( const std::string &type, const ValueFactory &payloadFactory, - const EventPriority &priority) const { + EventPriority priority, + RawEvent::Category category) const { SystraceSection s("EventEmitter::dispatchEvent"); auto eventDispatcher = eventDispatcher_.lock(); @@ -73,7 +79,8 @@ void EventEmitter::dispatchEvent( } eventDispatcher->dispatchEvent( - RawEvent(normalizeEventType(type), payloadFactory, eventTarget_), + RawEvent( + normalizeEventType(type), payloadFactory, eventTarget_, category), priority); } @@ -87,8 +94,11 @@ void EventEmitter::dispatchUniqueEvent( return; } - eventDispatcher->dispatchUniqueEvent( - RawEvent(normalizeEventType(type), payloadFactory, eventTarget_)); + eventDispatcher->dispatchUniqueEvent(RawEvent( + normalizeEventType(type), + payloadFactory, + eventTarget_, + RawEvent::Category::Continuous)); } void EventEmitter::setEnabled(bool enabled) const { diff --git a/ReactCommon/react/renderer/core/EventEmitter.h b/ReactCommon/react/renderer/core/EventEmitter.h index 55bdf8f040158c..cb3caa465d2ba0 100644 --- a/ReactCommon/react/renderer/core/EventEmitter.h +++ b/ReactCommon/react/renderer/core/EventEmitter.h @@ -71,12 +71,17 @@ class EventEmitter { const std::string &type, const ValueFactory &payloadFactory = EventEmitter::defaultPayloadFactory(), - const EventPriority &priority = EventPriority::AsynchronousBatched) const; + EventPriority priority = EventPriority::AsynchronousBatched, + RawEvent::Category category = RawEvent::Category::Unspecified) const; void dispatchEvent( const std::string &type, const folly::dynamic &payload, - const EventPriority &priority = EventPriority::AsynchronousBatched) const; + EventPriority priority = EventPriority::AsynchronousBatched) const; + + void dispatchUniqueEvent( + const std::string &type, + const folly::dynamic &payload) const; void dispatchUniqueEvent( const std::string &type, diff --git a/ReactCommon/react/renderer/core/EventPipe.h b/ReactCommon/react/renderer/core/EventPipe.h index b0264579ae0409..3e9ac127e6bb06 100644 --- a/ReactCommon/react/renderer/core/EventPipe.h +++ b/ReactCommon/react/renderer/core/EventPipe.h @@ -12,6 +12,7 @@ #include #include +#include #include namespace facebook { @@ -21,6 +22,7 @@ using EventPipe = std::function; } // namespace react diff --git a/ReactCommon/react/renderer/core/EventPriority.h b/ReactCommon/react/renderer/core/EventPriority.h index 61e3ad39dbdf5e..8611f105800e0e 100644 --- a/ReactCommon/react/renderer/core/EventPriority.h +++ b/ReactCommon/react/renderer/core/EventPriority.h @@ -10,7 +10,7 @@ namespace facebook { namespace react { -enum class EventPriority : int { +enum class EventPriority { SynchronousUnbatched, SynchronousBatched, AsynchronousUnbatched, diff --git a/ReactCommon/react/renderer/core/EventQueue.cpp b/ReactCommon/react/renderer/core/EventQueue.cpp index 639d29a4751729..4d10e4c74423ac 100644 --- a/ReactCommon/react/renderer/core/EventQueue.cpp +++ b/ReactCommon/react/renderer/core/EventQueue.cpp @@ -14,26 +14,54 @@ namespace facebook { namespace react { EventQueue::EventQueue( - EventPipe eventPipe, - StatePipe statePipe, + EventQueueProcessor eventProcessor, std::unique_ptr eventBeat) - : eventPipe_(std::move(eventPipe)), - statePipe_(std::move(statePipe)), + : eventProcessor_(std::move(eventProcessor)), eventBeat_(std::move(eventBeat)) { eventBeat_->setBeatCallback( std::bind(&EventQueue::onBeat, this, std::placeholders::_1)); } -void EventQueue::enqueueEvent(const RawEvent &rawEvent) const { +void EventQueue::enqueueEvent(RawEvent &&rawEvent) const { { std::lock_guard lock(queueMutex_); - eventQueue_.push_back(rawEvent); + eventQueue_.push_back(std::move(rawEvent)); } onEnqueue(); } -void EventQueue::enqueueStateUpdate(const StateUpdate &stateUpdate) const { +void EventQueue::enqueueUniqueEvent(RawEvent &&rawEvent) const { + { + std::lock_guard lock(queueMutex_); + + auto repeatedEvent = eventQueue_.rend(); + + for (auto it = eventQueue_.rbegin(); it != eventQueue_.rend(); ++it) { + if (it->type == rawEvent.type && + it->eventTarget == rawEvent.eventTarget) { + repeatedEvent = it; + break; + } else if (it->eventTarget == rawEvent.eventTarget) { + // It is necessary to maintain order of different event types + // for the same target. If the same target has event types A1, B1 + // in the event queue and event A2 occurs. A1 has to stay in the + // queue. + break; + } + } + + if (repeatedEvent == eventQueue_.rend()) { + eventQueue_.push_back(std::move(rawEvent)); + } else { + *repeatedEvent = std::move(rawEvent); + } + } + + onEnqueue(); +} + +void EventQueue::enqueueStateUpdate(StateUpdate &&stateUpdate) const { { std::lock_guard lock(queueMutex_); if (!stateUpdateQueue_.empty()) { @@ -42,15 +70,15 @@ void EventQueue::enqueueStateUpdate(const StateUpdate &stateUpdate) const { stateUpdateQueue_.pop_back(); } } - stateUpdateQueue_.push_back(stateUpdate); + stateUpdateQueue_.push_back(std::move(stateUpdate)); } onEnqueue(); } void EventQueue::onBeat(jsi::Runtime &runtime) const { - flushEvents(runtime); flushStateUpdates(); + flushEvents(runtime); } void EventQueue::flushEvents(jsi::Runtime &runtime) const { @@ -67,30 +95,7 @@ void EventQueue::flushEvents(jsi::Runtime &runtime) const { eventQueue_.clear(); } - { - std::lock_guard lock(EventEmitter::DispatchMutex()); - - for (const auto &event : queue) { - if (event.eventTarget) { - event.eventTarget->retain(runtime); - } - } - } - - for (const auto &event : queue) { - eventPipe_( - runtime, event.eventTarget.get(), event.type, event.payloadFactory); - } - - // No need to lock `EventEmitter::DispatchMutex()` here. - // The mutex protects from a situation when the `instanceHandle` can be - // deallocated during accessing, but that's impossible at this point because - // we have a strong pointer to it. - for (const auto &event : queue) { - if (event.eventTarget) { - event.eventTarget->release(runtime); - } - } + eventProcessor_.flushEvents(runtime, std::move(queue)); } void EventQueue::flushStateUpdates() const { @@ -107,9 +112,7 @@ void EventQueue::flushStateUpdates() const { stateUpdateQueue_.clear(); } - for (const auto &stateUpdate : stateUpdateQueue) { - statePipe_(stateUpdate); - } + eventProcessor_.flushStateUpdates(std::move(stateUpdateQueue)); } } // namespace react diff --git a/ReactCommon/react/renderer/core/EventQueue.h b/ReactCommon/react/renderer/core/EventQueue.h index ed77cad3f6157d..d0f9da84426dfa 100644 --- a/ReactCommon/react/renderer/core/EventQueue.h +++ b/ReactCommon/react/renderer/core/EventQueue.h @@ -13,9 +13,8 @@ #include #include -#include +#include #include -#include #include namespace facebook { @@ -28,8 +27,7 @@ namespace react { class EventQueue { public: EventQueue( - EventPipe eventPipe, - StatePipe statePipe, + EventQueueProcessor eventProcessor, std::unique_ptr eventBeat); virtual ~EventQueue() = default; @@ -37,13 +35,20 @@ class EventQueue { * Enqueues and (probably later) dispatch a given event. * Can be called on any thread. */ - void enqueueEvent(const RawEvent &rawEvent) const; + void enqueueEvent(RawEvent &&rawEvent) const; + + /* + * Enqueues and (probably later) dispatches a given event. + * Deletes last RawEvent from the queue if it has the same type and target. + * Can be called on any thread. + */ + void enqueueUniqueEvent(RawEvent &&rawEvent) const; /* * Enqueues and (probably later) dispatch a given state update. * Can be called on any thread. */ - void enqueueStateUpdate(const StateUpdate &stateUpdate) const; + void enqueueStateUpdate(StateUpdate &&stateUpdate) const; protected: /* @@ -57,13 +62,14 @@ class EventQueue { void flushEvents(jsi::Runtime &runtime) const; void flushStateUpdates() const; - const EventPipe eventPipe_; - const StatePipe statePipe_; + EventQueueProcessor eventProcessor_; + const std::unique_ptr eventBeat_; // Thread-safe, protected by `queueMutex_`. mutable std::vector eventQueue_; mutable std::vector stateUpdateQueue_; mutable std::mutex queueMutex_; + mutable bool hasContinuousEventStarted_{false}; }; } // namespace react diff --git a/ReactCommon/react/renderer/core/EventQueueProcessor.cpp b/ReactCommon/react/renderer/core/EventQueueProcessor.cpp new file mode 100644 index 00000000000000..40b813e155aa93 --- /dev/null +++ b/ReactCommon/react/renderer/core/EventQueueProcessor.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "EventQueue.h" + +#include "EventEmitter.h" +#include "ShadowNodeFamily.h" + +namespace facebook { +namespace react { + +EventQueueProcessor::EventQueueProcessor( + EventPipe eventPipe, + StatePipe statePipe) + : eventPipe_(std::move(eventPipe)), statePipe_(std::move(statePipe)) {} + +void EventQueueProcessor::flushEvents( + jsi::Runtime &runtime, + std::vector &&events) const { + { + std::lock_guard lock(EventEmitter::DispatchMutex()); + + for (const auto &event : events) { + if (event.eventTarget) { + event.eventTarget->retain(runtime); + } + } + } + + for (auto const &event : events) { + if (event.category == RawEvent::Category::ContinuousEnd) { + hasContinuousEventStarted_ = false; + } + + auto reactPriority = hasContinuousEventStarted_ + ? ReactEventPriority::Default + : ReactEventPriority::Discrete; + + if (event.category == RawEvent::Category::Continuous) { + reactPriority = ReactEventPriority::Default; + } + + if (event.category == RawEvent::Category::Discrete) { + reactPriority = ReactEventPriority::Discrete; + } + + eventPipe_( + runtime, + event.eventTarget.get(), + event.type, + reactPriority, + event.payloadFactory); + + if (event.category == RawEvent::Category::ContinuousStart) { + hasContinuousEventStarted_ = true; + } + } + + // No need to lock `EventEmitter::DispatchMutex()` here. + // The mutex protects from a situation when the `instanceHandle` can be + // deallocated during accessing, but that's impossible at this point because + // we have a strong pointer to it. + for (const auto &event : events) { + if (event.eventTarget) { + event.eventTarget->release(runtime); + } + } +} + +void EventQueueProcessor::flushStateUpdates( + std::vector &&states) const { + for (const auto &stateUpdate : states) { + statePipe_(stateUpdate); + } +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/react/renderer/core/EventQueueProcessor.h b/ReactCommon/react/renderer/core/EventQueueProcessor.h new file mode 100644 index 00000000000000..933cc9a207961c --- /dev/null +++ b/ReactCommon/react/renderer/core/EventQueueProcessor.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace facebook { +namespace react { + +class EventQueueProcessor { + public: + EventQueueProcessor(EventPipe eventPipe, StatePipe statePipe); + + void flushEvents(jsi::Runtime &runtime, std::vector &&events) const; + void flushStateUpdates(std::vector &&states) const; + + private: + EventPipe const eventPipe_; + StatePipe const statePipe_; + + mutable bool hasContinuousEventStarted_{false}; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/react/renderer/core/LayoutConstraints.h b/ReactCommon/react/renderer/core/LayoutConstraints.h index cb166c81da8bfb..26b4c419e38c6b 100644 --- a/ReactCommon/react/renderer/core/LayoutConstraints.h +++ b/ReactCommon/react/renderer/core/LayoutConstraints.h @@ -40,6 +40,12 @@ inline bool operator==( std::tie(rhs.minimumSize, rhs.maximumSize, rhs.layoutDirection); } +inline bool operator!=( + const LayoutConstraints &lhs, + const LayoutConstraints &rhs) { + return !(lhs == rhs); +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/react/renderer/core/RawEvent.cpp b/ReactCommon/react/renderer/core/RawEvent.cpp index 7782e7cbe8bdfc..3abace5171e2e0 100644 --- a/ReactCommon/react/renderer/core/RawEvent.cpp +++ b/ReactCommon/react/renderer/core/RawEvent.cpp @@ -13,10 +13,12 @@ namespace react { RawEvent::RawEvent( std::string type, ValueFactory payloadFactory, - SharedEventTarget eventTarget) + SharedEventTarget eventTarget, + Category category) : type(std::move(type)), payloadFactory(std::move(payloadFactory)), - eventTarget(std::move(eventTarget)) {} + eventTarget(std::move(eventTarget)), + category(category) {} } // namespace react } // namespace facebook diff --git a/ReactCommon/react/renderer/core/RawEvent.h b/ReactCommon/react/renderer/core/RawEvent.h index 03286a2ac089c4..fc3de781d2b8b3 100644 --- a/ReactCommon/react/renderer/core/RawEvent.h +++ b/ReactCommon/react/renderer/core/RawEvent.h @@ -19,16 +19,53 @@ namespace react { /* * Represents ready-to-dispatch event object. */ -class RawEvent { - public: +struct RawEvent { + /* + * Defines category of a native platform event. This is used to deduce types + * of events for Concurrent Mode. + */ + enum class Category { + /* + * Start of a continuous event. To be used with touchStart. + */ + ContinuousStart, + + /* + * End of a continuous event. To be used with touchEnd. + */ + ContinuousEnd, + + /* + * Priority for this event will be determined from other events in the + * queue. If it is triggered by continuous event, its priority will be + * default. If it is not triggered by continuous event, its priority will be + * discrete. + */ + Unspecified, + + /* + * Forces discrete type for the event. Regardless if continuous event is + * ongoing. + */ + Discrete, + + /* + * Forces continuous type for the event. Regardless if continuous event + * isn't ongoing. + */ + Continuous + }; + RawEvent( std::string type, ValueFactory payloadFactory, - SharedEventTarget eventTarget); + SharedEventTarget eventTarget, + Category category = Category::Unspecified); std::string type; ValueFactory payloadFactory; SharedEventTarget eventTarget; + Category category; }; } // namespace react diff --git a/ReactCommon/react/renderer/core/RawPropsKeyMap.cpp b/ReactCommon/react/renderer/core/RawPropsKeyMap.cpp index 0ae4c9a3a2711b..af24fdb4a986b7 100644 --- a/ReactCommon/react/renderer/core/RawPropsKeyMap.cpp +++ b/ReactCommon/react/renderer/core/RawPropsKeyMap.cpp @@ -63,7 +63,7 @@ void RawPropsKeyMap::reindex() noexcept { buckets_.resize(kPropNameLengthHardCap); auto length = RawPropsPropNameLength{0}; - for (auto i = 0; i < items_.size(); i++) { + for (size_t i = 0; i < items_.size(); i++) { auto &item = items_[i]; if (item.length != length) { for (auto j = length; j < item.length; j++) { diff --git a/ReactCommon/react/renderer/core/RawPropsParser.cpp b/ReactCommon/react/renderer/core/RawPropsParser.cpp index 81142f3aa1f266..db098e9fab5bc7 100644 --- a/ReactCommon/react/renderer/core/RawPropsParser.cpp +++ b/ReactCommon/react/renderer/core/RawPropsParser.cpp @@ -114,7 +114,7 @@ void RawPropsParser::preparse(RawProps const &rawProps) const noexcept { auto count = names.size(runtime); auto valueIndex = RawPropsValueIndex{0}; - for (auto i = 0; i < count; i++) { + for (size_t i = 0; i < count; i++) { auto nameValue = names.getValueAtIndex(runtime, i).getString(runtime); auto value = object.getProperty(runtime, nameValue); diff --git a/ReactCommon/react/renderer/core/ReactEventPriority.h b/ReactCommon/react/renderer/core/ReactEventPriority.h new file mode 100644 index 00000000000000..3ef8b5728ebd43 --- /dev/null +++ b/ReactCommon/react/renderer/core/ReactEventPriority.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +namespace facebook { +namespace react { + +/* + * An enum that represents React's event priority. + * Used to map Fabric events to React. + */ +enum class ReactEventPriority { + /* + * Event priority is unspecified. + */ + Default, + + /* + * User events that happen at discrete times, like + * input into text field. + */ + Discrete, + + /* + * “fluid” user events that happen many times over a short period of time like + * scrolling. + */ + Continuous, +}; + +static constexpr std::underlying_type::type serialize( + ReactEventPriority reactEventPriority) { + return static_cast::type>( + reactEventPriority); +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/react/renderer/core/ShadowNode.cpp b/ReactCommon/react/renderer/core/ShadowNode.cpp index c96b7a223c9a94..846170e0063828 100644 --- a/ReactCommon/react/renderer/core/ShadowNode.cpp +++ b/ReactCommon/react/renderer/core/ShadowNode.cpp @@ -213,7 +213,7 @@ void ShadowNode::replaceChild( *std::const_pointer_cast(children_); auto size = children.size(); - if (suggestedIndex != -1 && suggestedIndex < size) { + if (suggestedIndex != -1 && static_cast(suggestedIndex) < size) { // If provided `suggestedIndex` is accurate, // replacing in place using the index. if (children.at(suggestedIndex).get() == &oldChild) { @@ -222,7 +222,7 @@ void ShadowNode::replaceChild( } } - for (auto index = 0; index < size; index++) { + for (size_t index = 0; index < size; index++) { if (children.at(index).get() == &oldChild) { children[index] = newChild; return; diff --git a/ReactCommon/react/renderer/core/propsConversions.h b/ReactCommon/react/renderer/core/propsConversions.h index cb3f1665fc0fb5..3add7a18082ccb 100644 --- a/ReactCommon/react/renderer/core/propsConversions.h +++ b/ReactCommon/react/renderer/core/propsConversions.h @@ -30,7 +30,7 @@ void fromRawValue(RawValue const &rawValue, std::vector &result) { auto length = items.size(); result.clear(); result.reserve(length); - for (int i = 0; i < length; i++) { + for (size_t i = 0; i < length; i++) { T itemResult; fromRawValue(items.at(i), itemResult); result.push_back(itemResult); diff --git a/ReactCommon/react/renderer/core/tests/ConcreteShadowNodeTest.cpp b/ReactCommon/react/renderer/core/tests/ConcreteShadowNodeTest.cpp index de48a4b6e7b566..0b2d025d08ad40 100644 --- a/ReactCommon/react/renderer/core/tests/ConcreteShadowNodeTest.cpp +++ b/ReactCommon/react/renderer/core/tests/ConcreteShadowNodeTest.cpp @@ -26,7 +26,7 @@ TEST(ConcreteShadowNodeTest, testSetStateData) { auto shadowNode = builder.build(element); - shadowNode->setStateData({{10, 11}, {{21, 22}, {301, 302}}}); + shadowNode->setStateData({{10, 11}, {{21, 22}, {301, 302}}, 0}); EXPECT_NE( shadowNode->getState(), shadowNode->getFamily().getMostRecentState()); diff --git a/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp b/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp new file mode 100644 index 00000000000000..268a6a0aca903f --- /dev/null +++ b/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include +#include +#include + +#include + +namespace facebook::react { + +class EventQueueProcessorTest : public testing::Test { + protected: + void SetUp() override { + runtime_ = facebook::hermes::makeHermesRuntime(); + + auto eventPipe = [this]( + jsi::Runtime &runtime, + const EventTarget *eventTarget, + const std::string &type, + ReactEventPriority priority, + const ValueFactory &payloadFactory) { + eventTypes_.push_back(type); + eventPriorities_.push_back(priority); + }; + + auto dummyStatePipe = [](StateUpdate const &stateUpdate) {}; + + eventProcessor_ = + std::make_unique(eventPipe, dummyStatePipe); + } + + std::unique_ptr runtime_; + std::unique_ptr eventProcessor_; + std::vector eventTypes_; + std::vector eventPriorities_; + ValueFactory dummyValueFactory_; +}; + +TEST_F(EventQueueProcessorTest, singleUnspecifiedEvent) { + eventProcessor_->flushEvents( + *runtime_, + {RawEvent( + "my type", + dummyValueFactory_, + nullptr, + RawEvent::Category::Unspecified)}); + + EXPECT_EQ(eventPriorities_.size(), 1); + EXPECT_EQ(eventTypes_[0], "my type"); + EXPECT_EQ(eventPriorities_[0], ReactEventPriority::Discrete); +} + +TEST_F(EventQueueProcessorTest, continiousEvent) { + eventProcessor_->flushEvents( + *runtime_, + {RawEvent( + "touchStart", + dummyValueFactory_, + nullptr, + RawEvent::Category::ContinuousStart), + RawEvent( + "touchMove", + dummyValueFactory_, + nullptr, + RawEvent::Category::Unspecified), + RawEvent( + "touchEnd", + dummyValueFactory_, + nullptr, + RawEvent::Category::ContinuousEnd), + RawEvent( + "custom event", + dummyValueFactory_, + nullptr, + RawEvent::Category::Unspecified)}); + + EXPECT_EQ(eventPriorities_.size(), 4); + + EXPECT_EQ(eventTypes_[0], "touchStart"); + EXPECT_EQ(eventPriorities_[0], ReactEventPriority::Discrete); + + EXPECT_EQ(eventTypes_[1], "touchMove"); + EXPECT_EQ(eventPriorities_[1], ReactEventPriority::Default); + + EXPECT_EQ(eventTypes_[2], "touchEnd"); + EXPECT_EQ(eventPriorities_[2], ReactEventPriority::Discrete); + + EXPECT_EQ(eventTypes_[3], "custom event"); + EXPECT_EQ(eventPriorities_[3], ReactEventPriority::Discrete); +} + +TEST_F(EventQueueProcessorTest, alwaysContinuousEvent) { + eventProcessor_->flushEvents( + *runtime_, + { + RawEvent( + "onScroll", + dummyValueFactory_, + nullptr, + RawEvent::Category::Continuous), + }); + + EXPECT_EQ(eventPriorities_.size(), 1); + + EXPECT_EQ(eventTypes_[0], "onScroll"); + EXPECT_EQ(eventPriorities_[0], ReactEventPriority::Default); +} + +TEST_F(EventQueueProcessorTest, alwaysDiscreteEvent) { + eventProcessor_->flushEvents( + *runtime_, + { + RawEvent( + "onChange", + dummyValueFactory_, + nullptr, + RawEvent::Category::Discrete), + }); + + EXPECT_EQ(eventPriorities_.size(), 1); + + EXPECT_EQ(eventTypes_[0], "onChange"); + EXPECT_EQ(eventPriorities_[0], ReactEventPriority::Discrete); +} + +} // namespace facebook::react diff --git a/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp b/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp index 7bb589914edd8d..2e54fc8bf02f88 100644 --- a/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp +++ b/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp @@ -191,9 +191,10 @@ TEST(RawPropsTest, handleRawPropsSingleIntGetManyTimes) { } TEST(RawPropsTest, handleRawPropsPrimitiveTypes) { - const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)( - "doubleValue", (double)17.42)("floatValue", (float)66.67)( - "stringValue", "helloworld")("boolValue", true)); + const auto &raw = RawProps( + folly::dynamic::object("intValue", (int)42)("doubleValue", (double)17.42)( + "floatValue", + (float)66.67)("stringValue", "helloworld")("boolValue", true)); auto parser = RawPropsParser(); parser.prepare(); @@ -209,9 +210,10 @@ TEST(RawPropsTest, handleRawPropsPrimitiveTypes) { } TEST(RawPropsTest, handleRawPropsPrimitiveTypesGetTwice) { - const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)( - "doubleValue", (double)17.42)("floatValue", (float)66.67)( - "stringValue", "helloworld")("boolValue", true)); + const auto &raw = RawProps( + folly::dynamic::object("intValue", (int)42)("doubleValue", (double)17.42)( + "floatValue", + (float)66.67)("stringValue", "helloworld")("boolValue", true)); auto parser = RawPropsParser(); parser.prepare(); @@ -235,9 +237,10 @@ TEST(RawPropsTest, handleRawPropsPrimitiveTypesGetTwice) { } TEST(RawPropsTest, handleRawPropsPrimitiveTypesGetOutOfOrder) { - const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)( - "doubleValue", (double)17.42)("floatValue", (float)66.67)( - "stringValue", "helloworld")("boolValue", true)); + const auto &raw = RawProps( + folly::dynamic::object("intValue", (int)42)("doubleValue", (double)17.42)( + "floatValue", + (float)66.67)("stringValue", "helloworld")("boolValue", true)); auto parser = RawPropsParser(); parser.prepare(); diff --git a/ReactCommon/react/renderer/debug/DebugStringConvertible.h b/ReactCommon/react/renderer/debug/DebugStringConvertible.h index da79c15afa3a04..8833211cd2599d 100644 --- a/ReactCommon/react/renderer/debug/DebugStringConvertible.h +++ b/ReactCommon/react/renderer/debug/DebugStringConvertible.h @@ -192,16 +192,16 @@ std::string getDebugChildrenDescription( return ""; } - auto trailing = options.format ? std::string{"\n"} : std::string{""}; + auto separator = options.format ? std::string{"\n"} : std::string{""}; auto childrenString = std::string{""}; options.depth++; for (auto child : getDebugChildren(object, options)) { - childrenString += getDebugDescription(child, options) + trailing; + childrenString += getDebugDescription(child, options) + separator; } - if (!childrenString.empty() && !trailing.empty()) { - // Removing trailing fragment. + if (!childrenString.empty() && !separator.empty()) { + // Removing separator fragment. childrenString.erase(childrenString.end() - 1); } @@ -230,16 +230,16 @@ std::string getDebugDescription( auto childrenString = getDebugChildrenDescription(object, options); auto propsString = getDebugPropsDescription(object, options); - auto leading = + auto prefix = options.format ? std::string(options.depth * 2, ' ') : std::string{""}; - auto trailing = options.format ? std::string{"\n"} : std::string{""}; + auto separator = options.format ? std::string{"\n"} : std::string{""}; - return leading + "<" + nameString + + return prefix + "<" + nameString + (valueString.empty() ? "" : "=" + valueString) + (propsString.empty() ? "" : " " + propsString) + (childrenString.empty() ? "/>" - : ">" + trailing + childrenString + trailing + - leading + ""); + : ">" + separator + childrenString + separator + + prefix + ""); } /* diff --git a/ReactCommon/react/renderer/graphics/React-graphics.podspec b/ReactCommon/react/renderer/graphics/React-graphics.podspec index 58c4a37392a2b1..3226ea93026c58 100644 --- a/ReactCommon/react/renderer/graphics/React-graphics.podspec +++ b/ReactCommon/react/renderer/graphics/React-graphics.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' Pod::Spec.new do |s| diff --git a/ReactCommon/react/renderer/graphics/Transform.cpp b/ReactCommon/react/renderer/graphics/Transform.cpp index 0f48c9d2d5cad8..f99db5fd2b44f9 100644 --- a/ReactCommon/react/renderer/graphics/Transform.cpp +++ b/ReactCommon/react/renderer/graphics/Transform.cpp @@ -190,7 +190,7 @@ Transform Transform::Interpolate( // transform If at any point we hit an "Arbitrary" Transform, return at that // point Transform result = Transform::Identity(); - for (int i = 0, j = 0; + for (size_t i = 0, j = 0; i < lhs.operations.size() || j < rhs.operations.size();) { bool haveLHS = i < lhs.operations.size(); bool haveRHS = j < rhs.operations.size(); diff --git a/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.cpp b/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.cpp index 92b738e5b33f9c..455ce60dc53718 100644 --- a/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.cpp +++ b/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.cpp @@ -10,6 +10,14 @@ namespace facebook { namespace react { +bool isColorMeaningful(SharedColor const &color) noexcept { + if (!color) { + return false; + } + + return colorComponentsFromColor(color).alpha > 0; +} + SharedColor colorFromComponents(ColorComponents components) { float ratio = 255; return SharedColor( diff --git a/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h b/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h index 5ab4dabd56874d..34c7f6f53f3eb8 100644 --- a/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h +++ b/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h @@ -59,6 +59,7 @@ class SharedColor { Color color_; }; +bool isColorMeaningful(SharedColor const &color) noexcept; SharedColor colorFromComponents(ColorComponents components); ColorComponents colorComponentsFromColor(SharedColor color); diff --git a/ReactCommon/react/renderer/graphics/platform/ios/Color.cpp b/ReactCommon/react/renderer/graphics/platform/ios/Color.cpp index 0b9bf45c56d4cd..0c42253b94e9d5 100644 --- a/ReactCommon/react/renderer/graphics/platform/ios/Color.cpp +++ b/ReactCommon/react/renderer/graphics/platform/ios/Color.cpp @@ -11,6 +11,14 @@ namespace facebook { namespace react { +bool isColorMeaningful(SharedColor const &color) noexcept { + if (!color) { + return false; + } + + return colorComponentsFromColor(color).alpha > 0; +} + SharedColor colorFromComponents(ColorComponents components) { float ratio = 255; return SharedColor( diff --git a/ReactCommon/react/renderer/graphics/platform/ios/Color.h b/ReactCommon/react/renderer/graphics/platform/ios/Color.h index e85a92fffac11e..bd57a2f9ba6cea 100644 --- a/ReactCommon/react/renderer/graphics/platform/ios/Color.h +++ b/ReactCommon/react/renderer/graphics/platform/ios/Color.h @@ -20,6 +20,7 @@ using Color = int32_t; using SharedColor = better::optional; +bool isColorMeaningful(SharedColor const &color) noexcept; SharedColor colorFromComponents(ColorComponents components); ColorComponents colorComponentsFromColor(SharedColor color); diff --git a/ReactCommon/react/renderer/leakchecker/LeakChecker.cpp b/ReactCommon/react/renderer/leakchecker/LeakChecker.cpp index e2fd62f0ccc717..a72e485665f2e1 100644 --- a/ReactCommon/react/renderer/leakchecker/LeakChecker.cpp +++ b/ReactCommon/react/renderer/leakchecker/LeakChecker.cpp @@ -8,15 +8,13 @@ #include "LeakChecker.h" #include +#include namespace facebook { namespace react { -LeakChecker::LeakChecker( - RuntimeExecutor const &runtimeExecutor, - GarbageCollectionTrigger const &garbageCollectionTrigger) - : runtimeExecutor_(runtimeExecutor), - garbageCollectionTrigger_(garbageCollectionTrigger) {} +LeakChecker::LeakChecker(RuntimeExecutor const &runtimeExecutor) + : runtimeExecutor_(runtimeExecutor) {} void LeakChecker::uiManagerDidCreateShadowNodeFamily( ShadowNodeFamily::Shared const &shadowNodeFamily) const { @@ -24,13 +22,12 @@ void LeakChecker::uiManagerDidCreateShadowNodeFamily( } void LeakChecker::stopSurface(SurfaceId surfaceId) { - garbageCollectionTrigger_(); - if (previouslyStoppedSurface_ > 0) { // Dispatch the check onto JavaScript thread to make sure all other // cleanup code has had chance to run. runtimeExecutor_([previouslySoppedSurface = previouslyStoppedSurface_, - this](jsi::Runtime &) { + this](jsi::Runtime &runtime) { + runtime.instrumentation().collectGarbage("LeakChecker"); // For now check the previous surface because React uses double // buffering which keeps the surface that was just stopped in // memory. This is a documented problem in the last point of @@ -44,7 +41,7 @@ void LeakChecker::stopSurface(SurfaceId surfaceId) { void LeakChecker::checkSurfaceForLeaks(SurfaceId surfaceId) const { auto weakFamilies = registry_.weakFamiliesForSurfaceId(surfaceId); - uint numberOfLeaks = 0; + unsigned int numberOfLeaks = 0; for (auto const &weakFamily : weakFamilies) { auto strong = weakFamily.lock(); if (strong) { diff --git a/ReactCommon/react/renderer/leakchecker/LeakChecker.h b/ReactCommon/react/renderer/leakchecker/LeakChecker.h index 84bd4a5d8ea782..a9bb3dd004096c 100644 --- a/ReactCommon/react/renderer/leakchecker/LeakChecker.h +++ b/ReactCommon/react/renderer/leakchecker/LeakChecker.h @@ -20,9 +20,7 @@ using GarbageCollectionTrigger = std::function; class LeakChecker final { public: - LeakChecker( - RuntimeExecutor const &runtimeExecutor, - GarbageCollectionTrigger const &garbageCollectionTrigger); + LeakChecker(RuntimeExecutor const &runtimeExecutor); void uiManagerDidCreateShadowNodeFamily( ShadowNodeFamily::Shared const &shadowNodeFamily) const; @@ -32,7 +30,6 @@ class LeakChecker final { void checkSurfaceForLeaks(SurfaceId surfaceId) const; RuntimeExecutor const runtimeExecutor_{}; - GarbageCollectionTrigger const garbageCollectionTrigger_{}; WeakFamilyRegistry registry_{}; SurfaceId previouslyStoppedSurface_; diff --git a/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp b/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp index e923fe1143212c..80e76dfb4f2e03 100644 --- a/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp +++ b/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp @@ -12,7 +12,12 @@ using namespace facebook::react; namespace facebook { namespace react { -MapBuffer::MapBuffer(uint8_t *const data, uint16_t dataSize) { +// TODO T83483191: Extend MapBuffer C++ implementation to support basic random +// access +MapBuffer::MapBuffer(uint8_t *const data, int32_t dataSize) { + react_native_assert( + (data != nullptr) && "Error trying to build an invalid MapBuffer"); + // Should we move the memory here or document it? data_ = data; @@ -22,12 +27,13 @@ MapBuffer::MapBuffer(uint8_t *const data, uint16_t dataSize) { reinterpret_cast(data_ + HEADER_COUNT_OFFSET), UINT16_SIZE); - // TODO: extract memcpy calls into an inline function to simplify the code + // TODO T83483191: extract memcpy calls into an inline function to simplify + // the code dataSize_ = 0; memcpy( reinterpret_cast(&dataSize_), reinterpret_cast(data_ + HEADER_BUFFER_SIZE_OFFSET), - UINT16_SIZE); + INT_SIZE); if (dataSize != dataSize_) { LOG(ERROR) << "Error: Data size does not match, expected " << dataSize @@ -36,8 +42,8 @@ MapBuffer::MapBuffer(uint8_t *const data, uint16_t dataSize) { } } -int MapBuffer::getInt(Key key) const { - int value = 0; +int32_t MapBuffer::getInt(Key key) const { + int32_t value = 0; memcpy( reinterpret_cast(&value), reinterpret_cast(data_ + getValueOffset(key)), @@ -50,8 +56,8 @@ bool MapBuffer::getBool(Key key) const { } double MapBuffer::getDouble(Key key) const { - // TODO: extract this code into a "template method" and reuse it for other - // types + // TODO T83483191: extract this code into a "template method" and reuse it for + // other types double value = 0; memcpy( reinterpret_cast(&value), @@ -60,54 +66,52 @@ double MapBuffer::getDouble(Key key) const { return value; } -int MapBuffer::getDynamicDataOffset() const { +int32_t MapBuffer::getDynamicDataOffset() const { // The begininig of dynamic data can be calculated as the offset of the next // key in the map return getKeyOffset(count_); } std::string MapBuffer::getString(Key key) const { - // TODO Add checks to verify that offsets are under the boundaries of the map - // buffer - int dynamicDataOffset = getDynamicDataOffset(); - int stringLength = 0; + // TODO T83483191:Add checks to verify that offsets are under the boundaries + // of the map buffer + int32_t dynamicDataOffset = getDynamicDataOffset(); + int32_t stringLength = 0; + int32_t offset = getInt(key); memcpy( reinterpret_cast(&stringLength), - reinterpret_cast(data_ + dynamicDataOffset), + reinterpret_cast(data_ + dynamicDataOffset + offset), INT_SIZE); - int valueOffset = getInt(key) + sizeof(stringLength); - char *value = new char[stringLength]; memcpy( reinterpret_cast(value), - reinterpret_cast(data_ + dynamicDataOffset + valueOffset), + reinterpret_cast( + data_ + dynamicDataOffset + offset + INT_SIZE), stringLength); - return std::string(value); + return std::string(value, 0, stringLength); } MapBuffer MapBuffer::getMapBuffer(Key key) const { - // TODO Add checks to verify that offsets are under the boundaries of the map - // buffer - int dynamicDataOffset = getDynamicDataOffset(); - - uint16_t mapBufferLength = 0; + // TODO T83483191: Add checks to verify that offsets are under the boundaries + // of the map buffer + int32_t dynamicDataOffset = getDynamicDataOffset(); + int32_t mapBufferLength = 0; + int32_t offset = getInt(key); memcpy( reinterpret_cast(&mapBufferLength), - reinterpret_cast(data_ + dynamicDataOffset), - UINT16_SIZE); - - int valueOffset = getInt(key) + UINT16_SIZE; + reinterpret_cast(data_ + dynamicDataOffset + offset), + INT_SIZE); uint8_t *value = new Byte[mapBufferLength]; memcpy( reinterpret_cast(value), reinterpret_cast( - data_ + dynamicDataOffset + valueOffset), + data_ + dynamicDataOffset + offset + INT_SIZE), mapBufferLength); return MapBuffer(value, mapBufferLength); @@ -117,7 +121,7 @@ bool MapBuffer::isNull(Key key) const { return getInt(key) == NULL_VALUE; } -uint16_t MapBuffer::getBufferSize() const { +int32_t MapBuffer::getBufferSize() const { return dataSize_; } @@ -130,9 +134,8 @@ uint16_t MapBuffer::getCount() const { memcpy( reinterpret_cast(&size), - reinterpret_cast( - data_ + UINT16_SIZE), // TODO refactor this: + UINT16_SIZE describes - // the position in the header + reinterpret_cast(data_ + HEADER_COUNT_OFFSET), + UINT16_SIZE); return size; diff --git a/ReactCommon/react/renderer/mapbuffer/MapBuffer.h b/ReactCommon/react/renderer/mapbuffer/MapBuffer.h index ebe2c3336fde28..b3f0c3051f176f 100644 --- a/ReactCommon/react/renderer/mapbuffer/MapBuffer.h +++ b/ReactCommon/react/renderer/mapbuffer/MapBuffer.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include @@ -33,23 +34,23 @@ namespace react { class MapBuffer { private: // Buffer and its size - const uint8_t *data_; + const uint8_t *data_ = nullptr; // amount of bytes in the MapBuffer - uint16_t dataSize_; + int32_t dataSize_ = 0; // amount of items in the MapBuffer - uint16_t count_; + uint16_t count_ = 0; // returns the relative offset of the first byte of dynamic data - int getDynamicDataOffset() const; + int32_t getDynamicDataOffset() const; public: - MapBuffer(uint8_t *const data, uint16_t dataSize); + MapBuffer(uint8_t *const data, int32_t dataSize); ~MapBuffer(); - int getInt(Key key) const; + int32_t getInt(Key key) const; bool getBool(Key key) const; @@ -57,12 +58,12 @@ class MapBuffer { std::string getString(Key key) const; - // TODO: review this declaration + // TODO T83483191: review this declaration MapBuffer getMapBuffer(Key key) const; - uint16_t getBufferSize() const; + int32_t getBufferSize() const; - // TODO: review parameters of copy method + // TODO T83483191: review parameters of copy method void copy(uint8_t *output) const; bool isNull(Key key) const; diff --git a/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp b/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp index bed8ab88d5cb29..4ff2f7b5c58807 100644 --- a/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp +++ b/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp @@ -12,6 +12,7 @@ using namespace facebook::react; namespace facebook { namespace react { +// TODO T83483191: Add asserts to check overflowing on additions MapBufferBuilder::MapBufferBuilder() : MapBufferBuilder::MapBufferBuilder(INITIAL_KEY_VALUE_SIZE) {} @@ -32,10 +33,10 @@ MapBufferBuilder::MapBufferBuilder(uint16_t initialSize) { } void MapBufferBuilder::ensureKeyValueSpace() { - int oldKeyValuesSize = keyValuesSize_; + int32_t oldKeyValuesSize = keyValuesSize_; react_native_assert( - (keyValuesSize_ >= std::numeric_limits::max() / 2) && - "Error trying to assign a value beyond the capacity of uint16_t"); + (keyValuesSize_ < std::numeric_limits::max() / 2) && + "Error trying to assign a value beyond the capacity of uint16_t: "); keyValuesSize_ *= 2; uint8_t *newKeyValues = new Byte[keyValuesSize_]; uint8_t *oldKeyValues = keyValues_; @@ -44,7 +45,10 @@ void MapBufferBuilder::ensureKeyValueSpace() { delete[] oldKeyValues; } -void MapBufferBuilder::storeKeyValue(Key key, uint8_t *value, int valueSize) { +void MapBufferBuilder::storeKeyValue( + Key key, + uint8_t *value, + int32_t valueSize) { if (key < minKeyToStore_) { LOG(ERROR) << "Error: key out of order - key: " << key; abort(); @@ -54,12 +58,13 @@ void MapBufferBuilder::storeKeyValue(Key key, uint8_t *value, int valueSize) { << valueSize; abort(); } - // TODO: header.count points to the next index - // TODO: add test to verify storage of sparse keys - int keyOffset = getKeyOffset(_header.count); - int valueOffset = keyOffset + KEY_SIZE; - int nextKeyValueOffset = keyOffset + BUCKET_SIZE; + // TODO T83483191: header.count points to the next index + // TODO T83483191: add test to verify storage of sparse keys + int32_t keyOffset = getKeyOffset(_header.count); + int32_t valueOffset = keyOffset + KEY_SIZE; + + int32_t nextKeyValueOffset = keyOffset + BUCKET_SIZE; if (nextKeyValueOffset >= keyValuesSize_) { ensureKeyValueSpace(); } @@ -87,28 +92,32 @@ void MapBufferBuilder::putNull(Key key) { putInt(key, NULL_VALUE); } -void MapBufferBuilder::putInt(Key key, int value) { +void MapBufferBuilder::putInt(Key key, int32_t value) { uint8_t *bytePointer = reinterpret_cast(&(value)); storeKeyValue(key, bytePointer, INT_SIZE); } -void MapBufferBuilder::ensureDynamicDataSpace(int size) { +void MapBufferBuilder::ensureDynamicDataSpace(int32_t size) { if (dynamicDataValues_ == nullptr) { - dynamicDataSize_ = std::max(INITIAL_DYNAMIC_DATA_SIZE, size); + dynamicDataSize_ = size; dynamicDataValues_ = new Byte[dynamicDataSize_]; dynamicDataOffset_ = 0; return; } if (dynamicDataOffset_ + size >= dynamicDataSize_) { - int oldDynamicDataSize = dynamicDataSize_; - if (dynamicDataSize_ >= std::numeric_limits::max() / 2) { - LOG(ERROR) - << "Error: trying to assign a value beyond the capacity of uint16_t" - << static_cast(dynamicDataSize_) * 2; - abort(); - } - dynamicDataSize_ *= 2; + int32_t oldDynamicDataSize = dynamicDataSize_; + react_native_assert( + (dynamicDataSize_ < std::numeric_limits::max() / 2) && + "Error: trying to assign a value beyond the capacity of int"); + dynamicDataSize_ *= dynamicDataSize_; + + react_native_assert( + (dynamicDataSize_ < std::numeric_limits::max() - size) && + "Error: trying to assign a value beyond the capacity of int"); + + // sum size to ensure that the size always fit into newDynamicDataValues + dynamicDataSize_ += size; uint8_t *newDynamicDataValues = new Byte[dynamicDataSize_]; uint8_t *oldDynamicDataValues = dynamicDataValues_; memcpy(newDynamicDataValues, dynamicDataValues_, oldDynamicDataSize); @@ -118,15 +127,15 @@ void MapBufferBuilder::ensureDynamicDataSpace(int size) { } void MapBufferBuilder::putString(Key key, std::string value) { - int strLength = value.length(); + int32_t strLength = static_cast(value.length()); const char *cstring = getCstring(&value); // format [lenght of string (int)] + [Array of Characters in the string] - int sizeOfLength = INT_SIZE; - // TODO : review if map.getBufferSize() should be an int or long instead of an - // int16 (because strings can be longer than int16); + int32_t sizeOfLength = INT_SIZE; + // TODO T83483191: review if map.getBufferSize() should be an int32_t or long + // instead of an int16 (because strings can be longer than int16); - int sizeOfDynamicData = sizeOfLength + strLength; + int32_t sizeOfDynamicData = sizeOfLength + strLength; ensureDynamicDataSpace(sizeOfDynamicData); memcpy(dynamicDataValues_ + dynamicDataOffset_, &strLength, sizeOfLength); memcpy( @@ -141,17 +150,17 @@ void MapBufferBuilder::putString(Key key, std::string value) { } void MapBufferBuilder::putMapBuffer(Key key, MapBuffer &map) { - uint16_t mapBufferSize = map.getBufferSize(); + int32_t mapBufferSize = map.getBufferSize(); - // format [lenght of buffer (short)] + [Array of Characters in the string] - int sizeOfDynamicData = mapBufferSize + UINT16_SIZE; + // format [lenght of buffer (int)] + [bytes of MapBuffer] + int32_t sizeOfDynamicData = mapBufferSize + INT_SIZE; // format [Array of bytes of the mapBuffer] ensureDynamicDataSpace(sizeOfDynamicData); - memcpy(dynamicDataValues_ + dynamicDataOffset_, &mapBufferSize, UINT16_SIZE); + memcpy(dynamicDataValues_ + dynamicDataOffset_, &mapBufferSize, INT_SIZE); // Copy the content of the map into dynamicDataValues_ - map.copy(dynamicDataValues_ + dynamicDataOffset_ + UINT16_SIZE); + map.copy(dynamicDataValues_ + dynamicDataOffset_ + INT_SIZE); // Store Key and pointer to the string putInt(key, dynamicDataOffset_); @@ -160,8 +169,12 @@ void MapBufferBuilder::putMapBuffer(Key key, MapBuffer &map) { } MapBuffer MapBufferBuilder::build() { + react_native_assert( + (keyValues_ != nullptr) && + "Error when building mapbuffer with invalid datastructures."); + // Create buffer: [header] + [key, values] + [dynamic data] - int bufferSize = keyValuesOffset_ + dynamicDataOffset_; + int32_t bufferSize = keyValuesOffset_ + dynamicDataOffset_; _header.bufferSize = bufferSize; @@ -176,14 +189,15 @@ MapBuffer MapBufferBuilder::build() { memcpy(buffer + keyValuesOffset_, dynamicDataValues_, dynamicDataOffset_); } - // TODO: should we use std::move here? + // TODO T83483191: should we use std::move here? auto map = MapBuffer(buffer, bufferSize); - // TODO: we should invalidate the class once the build() method is + // TODO T83483191: we should invalidate the class once the build() method is // called. - // Reset internal data - delete[] keyValues_; + if (keyValues_ != nullptr) { + delete[] keyValues_; + } keyValues_ = nullptr; keyValuesSize_ = 0; keyValuesOffset_ = 0; @@ -194,6 +208,7 @@ MapBuffer MapBufferBuilder::build() { } dynamicDataSize_ = 0; dynamicDataOffset_ = 0; + _header = {ALIGNMENT, 0, 0}; return map; } diff --git a/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h b/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h index 31bfea181982f3..d46dd8fbea0a5f 100644 --- a/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h +++ b/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h @@ -16,11 +16,11 @@ namespace facebook { namespace react { // Default initial size for _keyValues array -// 106 = 10 entries = 10*10 + 6 sizeof(header) -constexpr uint16_t INITIAL_KEY_VALUE_SIZE = 106; +// 108 = 10 entries = 10*10 + 8 sizeof(header) +constexpr uint16_t INITIAL_KEY_VALUE_SIZE = 108; // Default initial size for _dynamicDataValues array -constexpr int INITIAL_DYNAMIC_DATA_SIZE = 200; +constexpr int32_t INITIAL_DYNAMIC_DATA_SIZE = 200; /** * MapBufferBuilder is a builder class for MapBuffer @@ -31,35 +31,35 @@ class MapBufferBuilder { void ensureKeyValueSpace(); - void ensureDynamicDataSpace(int size); + void ensureDynamicDataSpace(int32_t size); - void storeKeyValue(Key key, uint8_t *value, int valueSize); + void storeKeyValue(Key key, uint8_t *value, int32_t valueSize); // Array of [key,value] map entries: // - Key is represented in 2 bytes // - Value is stored into 8 bytes. The 8 bytes of the value will contain the // actual value for the key or a pointer to the actual value (based on the // type) - uint8_t *keyValues_; + uint8_t *keyValues_ = nullptr; // Amount of bytes allocated on _keyValues - uint16_t keyValuesSize_; + uint16_t keyValuesSize_ = 0; // Relative offset on the _keyValues array. // This represents the first byte that can be written in _keyValues array - int keyValuesOffset_; + int32_t keyValuesOffset_ = 0; // This array contains data for dynamic values in the MapBuffer. // A dynamic value is a String or another MapBuffer. - uint8_t *dynamicDataValues_; + uint8_t *dynamicDataValues_ = nullptr; // Amount of bytes allocated on _dynamicDataValues - uint16_t dynamicDataSize_; + int32_t dynamicDataSize_ = 0; // Relative offset on the _dynamicDataValues array. // This represents the first byte that can be written in _dynamicDataValues // array - int dynamicDataOffset_; + int32_t dynamicDataOffset_ = 0; // Minimmum key to store in the MapBuffer (this is used to guarantee // consistency) @@ -74,7 +74,7 @@ class MapBufferBuilder { static MapBuffer EMPTY(); - void putInt(Key key, int value); + void putInt(Key key, int32_t value); void putBool(Key key, bool value); @@ -86,7 +86,7 @@ class MapBufferBuilder { void putMapBuffer(Key key, MapBuffer &map); - // TODO This should return MapBuffer! + // TODO T83483191: This should return MapBuffer! MapBuffer build(); }; diff --git a/ReactCommon/react/renderer/mapbuffer/primitives.h b/ReactCommon/react/renderer/mapbuffer/primitives.h index ad153fd6f52647..456e0b9e12d1d1 100644 --- a/ReactCommon/react/renderer/mapbuffer/primitives.h +++ b/ReactCommon/react/renderer/mapbuffer/primitives.h @@ -9,11 +9,10 @@ #include -// TODO: Enable CHECK_CONSISTENCY only in debug mode or test environments (or -// just in demand) -// #define CHECK_CONSISTENCY 1 +// TODO T83483191: Enable CHECK_CONSISTENCY only in debug mode or test +// environments (or just in demand) #define CHECK_CONSISTENCY 1 -constexpr static int NULL_VALUE = 0; +constexpr static int32_t NULL_VALUE = 0; // Value used to verify if the data is serialized with LittleEndian order constexpr static uint16_t ALIGNMENT = 0xFE; @@ -28,36 +27,36 @@ namespace react { struct Header { uint16_t alignment; // alignment of serialization uint16_t count; // amount of items in the map - uint16_t bufferSize; // Amount of bytes used to store the map in memory + int32_t bufferSize; // Amount of bytes used to store the map in memory }; -constexpr static int KEY_SIZE = sizeof(Key); -constexpr static int HEADER_SIZE = sizeof(Header); -constexpr static int INT_SIZE = sizeof(int); -constexpr static int DOUBLE_SIZE = sizeof(double); -constexpr static int UINT8_SIZE = sizeof(uint8_t); -constexpr static int UINT16_SIZE = sizeof(uint16_t); -constexpr static int UINT64_SIZE = sizeof(uint64_t); -constexpr static int HEADER_ALIGNMENT_OFFSET = 0; -constexpr static int HEADER_COUNT_OFFSET = UINT16_SIZE; -constexpr static int HEADER_BUFFER_SIZE_OFFSET = UINT16_SIZE * 2; +constexpr static int32_t KEY_SIZE = sizeof(Key); +constexpr static int32_t HEADER_SIZE = sizeof(Header); +constexpr static int32_t INT_SIZE = sizeof(int32_t); +constexpr static int32_t DOUBLE_SIZE = sizeof(double); +constexpr static int32_t UINT8_SIZE = sizeof(uint8_t); +constexpr static int32_t UINT16_SIZE = sizeof(uint16_t); +constexpr static int32_t UINT64_SIZE = sizeof(uint64_t); +constexpr static int32_t HEADER_ALIGNMENT_OFFSET = 0; +constexpr static int32_t HEADER_COUNT_OFFSET = UINT16_SIZE; +constexpr static int32_t HEADER_BUFFER_SIZE_OFFSET = UINT16_SIZE * 2; -constexpr static int MAX_VALUE_SIZE = UINT64_SIZE; +constexpr static int32_t MAX_VALUE_SIZE = UINT64_SIZE; // 10 bytes : 2 key + 8 value -constexpr static int BUCKET_SIZE = KEY_SIZE + UINT64_SIZE; +constexpr static int32_t BUCKET_SIZE = KEY_SIZE + UINT64_SIZE; /** * Returns the offset of the key received by parameter. */ -inline int getKeyOffset(Key key) { +inline int32_t getKeyOffset(Key key) { return HEADER_SIZE + BUCKET_SIZE * key; } /** * Returns the offset of the value associated to the key received by parameter. */ -inline int getValueOffset(Key key) { +inline int32_t getValueOffset(Key key) { return getKeyOffset(key) + KEY_SIZE; } diff --git a/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp b/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp index cb18889cf76f7b..9dd36eeb6df997 100644 --- a/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp +++ b/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp @@ -70,7 +70,8 @@ TEST(MapBufferTest, testNullEntries) { EXPECT_EQ(map.getCount(), 2); EXPECT_EQ(map.isNull(0), true); EXPECT_EQ(map.isNull(1), false); - // TODO: serialize null values to be distinguishable from '0' values + // TODO T83483191: serialize null values to be distinguishable from '0' + // values // EXPECT_EQ(map.isNull(1), false); // EXPECT_EQ(map.getBool(1), false); } @@ -98,13 +99,24 @@ TEST(MapBufferTest, testStringEntries) { EXPECT_EQ(map.getString(0), "This is a test"); } +TEST(MapBufferTest, testUTFStringEntry) { + auto builder = MapBufferBuilder(); + + builder.putString(0, "Let's count: 的, 一, 是"); + auto map = builder.build(); + + EXPECT_EQ(map.getString(0), "Let's count: 的, 一, 是"); +} + TEST(MapBufferTest, testUTFStringEntries) { auto builder = MapBufferBuilder(); builder.putString(0, "Let's count: 的, 一, 是"); + builder.putString(1, "This is a test"); auto map = builder.build(); EXPECT_EQ(map.getString(0), "Let's count: 的, 一, 是"); + EXPECT_EQ(map.getString(1), "This is a test"); } TEST(MapBufferTest, testEmptyMap) { diff --git a/ReactCommon/react/renderer/mounting/BUCK b/ReactCommon/react/renderer/mounting/BUCK index 368aa113fdb896..2d0d42e5855a6f 100644 --- a/ReactCommon/react/renderer/mounting/BUCK +++ b/ReactCommon/react/renderer/mounting/BUCK @@ -88,5 +88,6 @@ fb_xplat_cxx_test( react_native_xplat_target("react/renderer/components/root:root"), react_native_xplat_target("react/renderer/components/view:view"), react_native_xplat_target("react/renderer/components/scrollview:scrollview"), + react_native_xplat_target("react/test_utils:test_utils"), ], ) diff --git a/ReactCommon/react/renderer/mounting/Differentiator.cpp b/ReactCommon/react/renderer/mounting/Differentiator.cpp index c23d7ee615354b..2773cd49e4f8cc 100644 --- a/ReactCommon/react/renderer/mounting/Differentiator.cpp +++ b/ReactCommon/react/renderer/mounting/Differentiator.cpp @@ -170,8 +170,8 @@ class TinyMap final { } better::small_vector vector_; - int numErased_{0}; - int erasedAtFront_{0}; + size_t numErased_{0}; + size_t erasedAtFront_{0}; }; /* @@ -336,7 +336,6 @@ static_assert( std::is_move_assignable::value, "`ShadowViewNodePair::NonOwningList` must be `move assignable`."); -// Forward declaration static void calculateShadowViewMutationsV2( BREADCRUMB_TYPE breadcrumb, ViewNodePairScope &scope, @@ -346,20 +345,40 @@ static void calculateShadowViewMutationsV2( ShadowViewNodePair::NonOwningList &&newChildPairs); struct OrderedMutationInstructionContainer { - ShadowViewMutation::List &createMutations; - ShadowViewMutation::List &deleteMutations; - ShadowViewMutation::List &insertMutations; - ShadowViewMutation::List &removeMutations; - ShadowViewMutation::List &updateMutations; - ShadowViewMutation::List &downwardMutations; - ShadowViewMutation::List &destructiveDownwardMutations; + ShadowViewMutation::List createMutations{}; + ShadowViewMutation::List deleteMutations{}; + ShadowViewMutation::List insertMutations{}; + ShadowViewMutation::List removeMutations{}; + ShadowViewMutation::List updateMutations{}; + ShadowViewMutation::List downwardMutations{}; + ShadowViewMutation::List destructiveDownwardMutations{}; }; +static void updateMatchedPairSubtrees( + BREADCRUMB_TYPE breadcrumb, + ViewNodePairScope &scope, + OrderedMutationInstructionContainer &mutationContainer, + TinyMap &newRemainingPairs, + ShadowViewNodePair::NonOwningList &oldChildPairs, + ShadowViewNodePair::NonOwningList &newChildPairs, + ShadowView const &parentShadowView, + ShadowViewNodePair const &oldPair, + ShadowViewNodePair const &newPair); + +static void updateMatchedPair( + BREADCRUMB_TYPE breadcrumb, + OrderedMutationInstructionContainer &mutationContainer, + bool oldNodeFoundInOrder, + bool newNodeFoundInOrder, + ShadowView const &parentShadowView, + ShadowViewNodePair const &oldPair, + ShadowViewNodePair const &newPair); + static void calculateShadowViewMutationsFlattener( BREADCRUMB_TYPE breadcrumb, ViewNodePairScope &scope, ReparentMode reparentMode, - OrderedMutationInstructionContainer &mutationInstructionContainer, + OrderedMutationInstructionContainer &mutationContainer, ShadowView const &parentShadowView, TinyMap &unvisitedFlattenedNodes, ShadowViewNodePair const &node, @@ -367,6 +386,199 @@ static void calculateShadowViewMutationsFlattener( TinyMap *parentSubVisitedOtherOldNodes = nullptr); +/** + * Updates the subtrees of any matched ShadowViewNodePair. This handles + * all cases of flattening/unflattening. + * + * This may modify data-structures passed to it and owned by the caller, + * specifically `newRemainingPairs`, and so the caller must also own + * the ViewNodePairScope used within. + */ +static void updateMatchedPairSubtrees( + BREADCRUMB_TYPE breadcrumb, + ViewNodePairScope &scope, + OrderedMutationInstructionContainer &mutationContainer, + TinyMap &newRemainingPairs, + ShadowViewNodePair::NonOwningList &oldChildPairs, + ShadowViewNodePair::NonOwningList &newChildPairs, + ShadowView const &parentShadowView, + ShadowViewNodePair const &oldPair, + ShadowViewNodePair const &newPair) { + // Are we flattening or unflattening either one? If node was + // flattened in both trees, there's no change, just continue. + if (oldPair.flattened && newPair.flattened) { + return; + } + + // We are either flattening or unflattening this node. + if (oldPair.flattened != newPair.flattened) { + DEBUG_LOGS({ + LOG(ERROR) + << "Differ: flattening or unflattening in updateMatchedPairSubtrees: [" + << oldPair.shadowView.tag << "] [" << newPair.shadowView.tag << "] " + << oldPair.flattened << " " << newPair.flattened << " with parent: [" + << parentShadowView.tag << "]"; + }); + + // Flattening + if (!oldPair.flattened) { + // Flatten old tree into new list + // At the end of this loop we still want to know which of these + // children are visited, so we reuse the `newRemainingPairs` + // map. + calculateShadowViewMutationsFlattener( + DIFF_BREADCRUMB( + "Flatten tree " + std::to_string(parentShadowView.tag) + + " into list " + std::to_string(oldPair.shadowView.tag)), + scope, + ReparentMode::Flatten, + mutationContainer, + parentShadowView, + newRemainingPairs, + oldPair); + } + // Unflattening + else { + // Construct unvisited nodes map + auto unvisitedOldChildPairs = TinyMap{}; + // We don't know where all the children of oldChildPair are + // within oldChildPairs, but we know that they're in the same + // relative order. The reason for this is because of flattening + // + zIndex: the children could be listed before the parent, + // interwoven with children from other nodes, etc. + auto oldFlattenedNodes = + sliceChildShadowNodeViewPairsFromViewNodePair(oldPair, scope, true); + for (size_t i = 0, j = 0; + i < oldChildPairs.size() && j < oldFlattenedNodes.size(); + i++) { + auto &oldChild = *oldChildPairs[i]; + if (oldChild.shadowView.tag == oldFlattenedNodes[j]->shadowView.tag) { + unvisitedOldChildPairs.insert({oldChild.shadowView.tag, &oldChild}); + j++; + } + } + + // Unflatten old list into new tree + calculateShadowViewMutationsFlattener( + DIFF_BREADCRUMB( + "Unflatten old list " + std::to_string(parentShadowView.tag) + + " into new tree " + std::to_string(newPair.shadowView.tag)), + scope, + ReparentMode::Unflatten, + mutationContainer, + parentShadowView, + unvisitedOldChildPairs, + newPair); + + // If old nodes were not visited, we know that we can delete + // them now. They will be removed from the hierarchy by the + // outermost loop of this function. + // TODO: is this necessary anymore? + for (auto &oldFlattenedNodePtr : oldFlattenedNodes) { + auto &oldFlattenedNode = *oldFlattenedNodePtr; + auto unvisitedOldChildPairIt = + unvisitedOldChildPairs.find(oldFlattenedNode.shadowView.tag); + if (unvisitedOldChildPairIt == unvisitedOldChildPairs.end()) { + // Node was visited - make sure to remove it from + // "newRemainingPairs" map + auto newRemainingIt = + newRemainingPairs.find(oldFlattenedNode.shadowView.tag); + if (newRemainingIt != newRemainingPairs.end()) { + newRemainingPairs.erase(newRemainingIt); + } + } + } + } + + return; + } + + // Update subtrees if View is not flattened, and if node addresses + // are not equal + if (oldPair.shadowNode != newPair.shadowNode) { + ViewNodePairScope innerScope{}; + auto oldGrandChildPairs = + sliceChildShadowNodeViewPairsFromViewNodePair(oldPair, innerScope); + auto newGrandChildPairs = + sliceChildShadowNodeViewPairsFromViewNodePair(newPair, innerScope); + calculateShadowViewMutationsV2( + DIFF_BREADCRUMB( + "Non-trivial update " + std::to_string(oldPair.shadowView.tag)), + innerScope, + *(newGrandChildPairs.size() + ? &mutationContainer.downwardMutations + : &mutationContainer.destructiveDownwardMutations), + oldPair.shadowView, + std::move(oldGrandChildPairs), + std::move(newGrandChildPairs)); + } +} + +/** + * Handle updates to a matched node pair, but NOT to their subtrees. + * + * Here we have (and need) knowledge of whether a node was found during + * in-order traversal, or out-of-order via a map lookup. Nodes are only REMOVEd + * or INSERTed when they are encountered via in-order-traversal, to ensure + * correct ordering of INSERT and REMOVE mutations. + */ +static void updateMatchedPair( + BREADCRUMB_TYPE breadcrumb, + OrderedMutationInstructionContainer &mutationContainer, + bool oldNodeFoundInOrder, + bool newNodeFoundInOrder, + ShadowView const &parentShadowView, + ShadowViewNodePair const &oldPair, + ShadowViewNodePair const &newPair) { + oldPair.otherTreePair = &newPair; + newPair.otherTreePair = &oldPair; + + // Check concrete-ness of views + // Create/Delete and Insert/Remove if necessary + if (oldPair.isConcreteView != newPair.isConcreteView) { + if (newPair.isConcreteView) { + if (newNodeFoundInOrder) { + mutationContainer.insertMutations.push_back( + ShadowViewMutation::InsertMutation( + parentShadowView, + newPair.shadowView, + static_cast(newPair.mountIndex))); + } + mutationContainer.createMutations.push_back( + ShadowViewMutation::CreateMutation(newPair.shadowView)); + } else { + if (oldNodeFoundInOrder) { + mutationContainer.removeMutations.push_back( + ShadowViewMutation::RemoveMutation( + parentShadowView, + oldPair.shadowView, + static_cast(oldPair.mountIndex))); + } + mutationContainer.deleteMutations.push_back( + ShadowViewMutation::DeleteMutation(oldPair.shadowView)); + } + } else if (oldPair.isConcreteView && newPair.isConcreteView) { + // If we found the old node by traversing, but not the new node, + // it means that there's some reordering requiring a REMOVE mutation. + if (oldNodeFoundInOrder && !newNodeFoundInOrder) { + mutationContainer.removeMutations.push_back( + ShadowViewMutation::RemoveMutation( + parentShadowView, + newPair.shadowView, + static_cast(oldPair.mountIndex))); + } + + // Even if node's children are flattened, it might still be a + // concrete view. The case where they're different is handled + // above. + if (oldPair.shadowView != newPair.shadowView) { + mutationContainer.updateMutations.push_back( + ShadowViewMutation::UpdateMutation( + oldPair.shadowView, newPair.shadowView)); + } + } +} + /** * Here we flatten or unflatten a subtree, given an unflattened node in either * the old or new tree, and a list of flattened nodes in the other tree. @@ -409,7 +621,7 @@ static void calculateShadowViewMutationsFlattener( BREADCRUMB_TYPE breadcrumb, ViewNodePairScope &scope, ReparentMode reparentMode, - OrderedMutationInstructionContainer &mutationInstructionContainer, + OrderedMutationInstructionContainer &mutationContainer, ShadowView const &parentShadowView, TinyMap &unvisitedOtherNodes, ShadowViewNodePair const &node, @@ -558,13 +770,13 @@ static void calculateShadowViewMutationsFlattener( react_native_assert(existsInOtherTree == treeChildPair.inOtherTree()); if (treeChildPair.inOtherTree() && treeChildPair.otherTreePair->isConcreteView) { - mutationInstructionContainer.removeMutations.push_back( + mutationContainer.removeMutations.push_back( ShadowViewMutation::RemoveMutation( node.shadowView, treeChildPair.otherTreePair->shadowView, static_cast(treeChildPair.mountIndex))); } else { - mutationInstructionContainer.removeMutations.push_back( + mutationContainer.removeMutations.push_back( ShadowViewMutation::RemoveMutation( node.shadowView, treeChildPair.shadowView, @@ -572,8 +784,8 @@ static void calculateShadowViewMutationsFlattener( } } else { // treeChildParent represents the "new" version of the node, so - // we can safely insert it - mutationInstructionContainer.insertMutations.push_back( + // we can safely insert it without checking in the other tree + mutationContainer.insertMutations.push_back( ShadowViewMutation::InsertMutation( node.shadowView, treeChildPair.shadowView, @@ -615,9 +827,13 @@ static void calculateShadowViewMutationsFlattener( continue; } + // TODO: compare ShadowNode pointer instead of ShadowView here? + // Or ShadowNode ptr comparison before comparing ShadowView, to allow for + // short-circuiting? ShadowView comparison is relatively expensive vs + // ShadowNode. if (newTreeNodePair.shadowView != oldTreeNodePair.shadowView && newTreeNodePair.isConcreteView && oldTreeNodePair.isConcreteView) { - mutationInstructionContainer.updateMutations.push_back( + mutationContainer.updateMutations.push_back( ShadowViewMutation::UpdateMutation( oldTreeNodePair.shadowView, newTreeNodePair.shadowView)); } @@ -631,7 +847,7 @@ static void calculateShadowViewMutationsFlattener( "(Un)Flattener trivial update of " + std::to_string(newTreeNodePair.shadowView.tag)), innerScope, - mutationInstructionContainer.downwardMutations, + mutationContainer.downwardMutations, newTreeNodePair.shadowView, sliceChildShadowNodeViewPairsFromViewNodePair( oldTreeNodePair, innerScope), @@ -662,7 +878,7 @@ static void calculateShadowViewMutationsFlattener( " old:" + std::to_string(treeChildPair.shadowView.tag)), scope, childReparentMode, - mutationInstructionContainer, + mutationContainer, (reparentMode == ReparentMode::Flatten ? parentShadowView : newTreeNodePair.shadowView), @@ -671,30 +887,32 @@ static void calculateShadowViewMutationsFlattener( subVisitedNewMap, subVisitedOldMap); } else { - // Unflatten parent, flatten child - if (childReparentMode == ReparentMode::Flatten) { - // Construct unvisited nodes map - auto unvisitedNewChildPairs = TinyMap{}; - // Memory note: these oldFlattenedNodes all disappear at the end - // of this "else" block, including any annotations we put on them. - auto newFlattenedNodes = - sliceChildShadowNodeViewPairsFromViewNodePair( - newTreeNodePair, scope, true); - for (size_t i = 0; i < newFlattenedNodes.size(); i++) { - auto &newChild = *newFlattenedNodes[i]; - - auto unvisitedOtherNodesIt = - unvisitedOtherNodes.find(newChild.shadowView.tag); - if (unvisitedOtherNodesIt != unvisitedOtherNodes.end()) { - auto unvisitedItPair = *unvisitedOtherNodesIt->second; - unvisitedNewChildPairs.insert( - {unvisitedItPair.shadowView.tag, &unvisitedItPair}); - } else { - unvisitedNewChildPairs.insert( - {newChild.shadowView.tag, &newChild}); - } + // Get flattened nodes from either new or old tree + auto flattenedNodes = sliceChildShadowNodeViewPairsFromViewNodePair( + (childReparentMode == ReparentMode::Flatten ? newTreeNodePair + : oldTreeNodePair), + scope, + true); + // Construct unvisited nodes map + auto unvisitedRecursiveChildPairs = + TinyMap{}; + for (size_t i = 0; i < flattenedNodes.size(); i++) { + auto &newChild = *flattenedNodes[i]; + + auto unvisitedOtherNodesIt = + unvisitedOtherNodes.find(newChild.shadowView.tag); + if (unvisitedOtherNodesIt != unvisitedOtherNodes.end()) { + auto unvisitedItPair = *unvisitedOtherNodesIt->second; + unvisitedRecursiveChildPairs.insert( + {unvisitedItPair.shadowView.tag, &unvisitedItPair}); + } else { + unvisitedRecursiveChildPairs.insert( + {newChild.shadowView.tag, &newChild}); } + } + // Unflatten parent, flatten child + if (childReparentMode == ReparentMode::Flatten) { // Flatten old tree into new list // At the end of this loop we still want to know which of these // children are visited, so we reuse the `newRemainingPairs` map. @@ -708,54 +926,17 @@ static void calculateShadowViewMutationsFlattener( " old:" + std::to_string(oldTreeNodePair.shadowView.tag)), scope, ReparentMode::Flatten, - mutationInstructionContainer, + mutationContainer, (reparentMode == ReparentMode::Flatten ? parentShadowView : newTreeNodePair.shadowView), - unvisitedNewChildPairs, + unvisitedRecursiveChildPairs, oldTreeNodePair, subVisitedNewMap, subVisitedOldMap); - - for (auto newFlattenedNode : newFlattenedNodes) { - auto unvisitedOldChildPairIt = - unvisitedNewChildPairs.find(newFlattenedNode->shadowView.tag); - - if (unvisitedOldChildPairIt == unvisitedNewChildPairs.end()) { - // Node was visited. - - auto deleteCreateIt = deletionCreationCandidatePairs.find( - newFlattenedNode->shadowView.tag); - if (deleteCreateIt != deletionCreationCandidatePairs.end()) { - deletionCreationCandidatePairs.erase(deleteCreateIt); - } - } - } } // Flatten parent, unflatten child else { - // Construct unvisited nodes map - auto unvisitedOldChildPairs = TinyMap{}; - // Memory note: these oldFlattenedNodes all disappear at the end - // of this "else" block, including any annotations we put on them. - auto oldFlattenedNodes = - sliceChildShadowNodeViewPairsFromViewNodePair( - oldTreeNodePair, scope, true); - for (size_t i = 0; i < oldFlattenedNodes.size(); i++) { - auto &oldChild = *oldFlattenedNodes[i]; - - auto unvisitedOtherNodesIt = - unvisitedOtherNodes.find(oldChild.shadowView.tag); - if (unvisitedOtherNodesIt != unvisitedOtherNodes.end()) { - auto &unvisitedItPair = *unvisitedOtherNodesIt->second; - unvisitedOldChildPairs.insert( - {unvisitedItPair.shadowView.tag, &unvisitedItPair}); - } else { - unvisitedOldChildPairs.insert( - {oldChild.shadowView.tag, &oldChild}); - } - } - // Unflatten old list into new tree calculateShadowViewMutationsFlattener( DIFF_BREADCRUMB( @@ -767,11 +948,11 @@ static void calculateShadowViewMutationsFlattener( " new:" + std::to_string(newTreeNodePair.shadowView.tag)), scope, ReparentMode::Unflatten, - mutationInstructionContainer, + mutationContainer, (reparentMode == ReparentMode::Flatten ? parentShadowView : newTreeNodePair.shadowView), - unvisitedOldChildPairs, + unvisitedRecursiveChildPairs, newTreeNodePair, subVisitedNewMap, subVisitedOldMap); @@ -779,69 +960,33 @@ static void calculateShadowViewMutationsFlattener( // If old nodes were not visited, we know that we can delete them // now. They will be removed from the hierarchy by the outermost // loop of this function. - for (auto oldFlattenedNode : oldFlattenedNodes) { - auto unvisitedOldChildPairIt = - unvisitedOldChildPairs.find(oldFlattenedNode->shadowView.tag); - if (unvisitedOldChildPairIt != unvisitedOldChildPairs.end()) { - // Node unvisited - mark the entire subtree for deletion - if (oldFlattenedNode->isConcreteView) { - Tag tag = oldFlattenedNode->shadowView.tag; - auto oldRemainingChildInListIt = std::find_if( - treeChildren.begin(), - treeChildren.end(), - [&tag](ShadowViewNodePair *nodePair) { - return nodePair->shadowView.tag == tag; - }); - if (oldRemainingChildInListIt != treeChildren.end()) { - auto deleteCreateIt = deletionCreationCandidatePairs.find( - oldFlattenedNode->shadowView.tag); - if (deleteCreateIt == - deletionCreationCandidatePairs.end()) { - deletionCreationCandidatePairs.insert( - {tag, *oldRemainingChildInListIt}); - } - } else { - // TODO: we might want to remove this block. It seems - // impossible to hit this logically (and empirically, - // after testing on lots of randomized and pathologically - // constructed trees) but I'm leaving this here out of an - // abundance of caution. - // In theory, this path should never be hit. If we don't - // see this in dev after a few months, let's delete this - // path. - react_native_assert(false); - mutationInstructionContainer.deleteMutations.push_back( - ShadowViewMutation::DeleteMutation( - oldFlattenedNode->shadowView)); - - calculateShadowViewMutationsV2( - DIFF_BREADCRUMB( - "Destroy " + - std::to_string(oldFlattenedNode->shadowView.tag)), - scope, - mutationInstructionContainer - .destructiveDownwardMutations, - oldFlattenedNode->shadowView, - sliceChildShadowNodeViewPairsFromViewNodePair( - *oldFlattenedNode, scope), - {}); - } + for (auto unvisitedOldChildPairIt = + unvisitedRecursiveChildPairs.begin(); + unvisitedOldChildPairIt != unvisitedRecursiveChildPairs.end(); + unvisitedOldChildPairIt++) { + if (unvisitedOldChildPairIt->first == 0) { + continue; + } + auto &oldFlattenedNode = *unvisitedOldChildPairIt->second; + + // Node unvisited - mark the entire subtree for deletion + if (oldFlattenedNode.isConcreteView && + !oldFlattenedNode.inOtherTree()) { + Tag tag = oldFlattenedNode.shadowView.tag; + auto deleteCreateIt = deletionCreationCandidatePairs.find( + oldFlattenedNode.shadowView.tag); + if (deleteCreateIt == deletionCreationCandidatePairs.end()) { + deletionCreationCandidatePairs.insert( + {tag, &oldFlattenedNode}); } } else { // Node was visited - make sure to remove it from // "newRemainingPairs" map auto newRemainingIt = - unvisitedOtherNodes.find(oldFlattenedNode->shadowView.tag); + unvisitedOtherNodes.find(oldFlattenedNode.shadowView.tag); if (newRemainingIt != unvisitedOtherNodes.end()) { unvisitedOtherNodes.erase(newRemainingIt); } - - // We also remove it from delete/creation candidates - auto deleteCreateIt = deletionCreationCandidatePairs.find( - oldFlattenedNode->shadowView.tag); - if (deleteCreateIt != deletionCreationCandidatePairs.end()) { - deletionCreationCandidatePairs.erase(deleteCreateIt); - } } } } @@ -854,10 +999,10 @@ static void calculateShadowViewMutationsFlattener( // delete/create if the Concreteness of the node has changed. if (newTreeNodePair.isConcreteView != oldTreeNodePair.isConcreteView) { if (newTreeNodePair.isConcreteView) { - mutationInstructionContainer.createMutations.push_back( + mutationContainer.createMutations.push_back( ShadowViewMutation::CreateMutation(newTreeNodePair.shadowView)); } else { - mutationInstructionContainer.deleteMutations.push_back( + mutationContainer.deleteMutations.push_back( ShadowViewMutation::DeleteMutation(oldTreeNodePair.shadowView)); } } @@ -866,10 +1011,6 @@ static void calculateShadowViewMutationsFlattener( {newTreeNodePair.shadowView.tag, &newTreeNodePair}); subVisitedOldMap->insert( {oldTreeNodePair.shadowView.tag, &oldTreeNodePair}); - - if (unvisitedIt != unvisitedOtherNodes.end()) { - unvisitedOtherNodes.erase(unvisitedIt); - } } else { // Node does not in exist in other tree. if (treeChildPair.isConcreteView && !treeChildPair.inOtherTree()) { @@ -894,13 +1035,17 @@ static void calculateShadowViewMutationsFlattener( } auto &treeChildPair = *it->second; - // If node was visited during a flattening/unflattening recursion. + // If node was visited during a flattening/unflattening recursion, + // and the node in the other tree is concrete, that means it was + // already created/deleted and we don't need to do that here. + // It is always the responsibility of the matcher to update subtrees when + // nodes are matched. if (treeChildPair.inOtherTree()) { continue; } if (reparentMode == ReparentMode::Flatten) { - mutationInstructionContainer.deleteMutations.push_back( + mutationContainer.deleteMutations.push_back( ShadowViewMutation::DeleteMutation(treeChildPair.shadowView)); if (!treeChildPair.flattened) { @@ -910,14 +1055,14 @@ static void calculateShadowViewMutationsFlattener( "Recursively delete tree child pair (flatten case): " + std::to_string(treeChildPair.shadowView.tag)), innerScope, - mutationInstructionContainer.destructiveDownwardMutations, + mutationContainer.destructiveDownwardMutations, treeChildPair.shadowView, sliceChildShadowNodeViewPairsFromViewNodePair( treeChildPair, innerScope), {}); } } else { - mutationInstructionContainer.createMutations.push_back( + mutationContainer.createMutations.push_back( ShadowViewMutation::CreateMutation(treeChildPair.shadowView)); if (!treeChildPair.flattened) { @@ -927,7 +1072,7 @@ static void calculateShadowViewMutationsFlattener( "Recursively delete tree child pair (unflatten case): " + std::to_string(treeChildPair.shadowView.tag)), innerScope, - mutationInstructionContainer.downwardMutations, + mutationContainer.downwardMutations, treeChildPair.shadowView, {}, sliceChildShadowNodeViewPairsFromViewNodePair( @@ -951,21 +1096,7 @@ static void calculateShadowViewMutationsV2( size_t index = 0; // Lists of mutations - auto createMutations = ShadowViewMutation::List{}; - auto deleteMutations = ShadowViewMutation::List{}; - auto insertMutations = ShadowViewMutation::List{}; - auto removeMutations = ShadowViewMutation::List{}; - auto updateMutations = ShadowViewMutation::List{}; - auto downwardMutations = ShadowViewMutation::List{}; - auto destructiveDownwardMutations = ShadowViewMutation::List{}; - auto mutationInstructionContainer = OrderedMutationInstructionContainer{ - createMutations, - deleteMutations, - insertMutations, - removeMutations, - updateMutations, - downwardMutations, - destructiveDownwardMutations}; + auto mutationContainer = OrderedMutationInstructionContainer{}; DEBUG_LOGS({ LOG(ERROR) << "Differ Entry: Child Pairs of node: [" << parentShadowView.tag @@ -1030,8 +1161,9 @@ static void calculateShadowViewMutationsV2( if (newChildPair.isConcreteView && oldChildPair.shadowView != newChildPair.shadowView) { - updateMutations.push_back(ShadowViewMutation::UpdateMutation( - oldChildPair.shadowView, newChildPair.shadowView)); + mutationContainer.updateMutations.push_back( + ShadowViewMutation::UpdateMutation( + oldChildPair.shadowView, newChildPair.shadowView)); } // Recursively update tree if ShadowNode pointers are not equal @@ -1047,8 +1179,9 @@ static void calculateShadowViewMutationsV2( "Stage 1: Recurse on " + std::to_string(oldChildPair.shadowView.tag)), innerScope, - *(newGrandChildPairs.size() ? &downwardMutations - : &destructiveDownwardMutations), + *(newGrandChildPairs.size() + ? &mutationContainer.downwardMutations + : &mutationContainer.destructiveDownwardMutations), oldChildPair.shadowView, std::move(oldGrandChildPairs), std::move(newGrandChildPairs)); @@ -1073,12 +1206,13 @@ static void calculateShadowViewMutationsV2( continue; } - deleteMutations.push_back( + mutationContainer.deleteMutations.push_back( ShadowViewMutation::DeleteMutation(oldChildPair.shadowView)); - removeMutations.push_back(ShadowViewMutation::RemoveMutation( - parentShadowView, - oldChildPair.shadowView, - static_cast(oldChildPair.mountIndex))); + mutationContainer.removeMutations.push_back( + ShadowViewMutation::RemoveMutation( + parentShadowView, + oldChildPair.shadowView, + static_cast(oldChildPair.mountIndex))); // We also have to call the algorithm recursively to clean up the entire // subtree starting from the removed view. @@ -1087,7 +1221,7 @@ static void calculateShadowViewMutationsV2( DIFF_BREADCRUMB( "Trivial delete " + std::to_string(oldChildPair.shadowView.tag)), innerScope, - destructiveDownwardMutations, + mutationContainer.destructiveDownwardMutations, oldChildPair.shadowView, sliceChildShadowNodeViewPairsFromViewNodePair( oldChildPair, innerScope), @@ -1109,11 +1243,12 @@ static void calculateShadowViewMutationsV2( continue; } - insertMutations.push_back(ShadowViewMutation::InsertMutation( - parentShadowView, - newChildPair.shadowView, - static_cast(newChildPair.mountIndex))); - createMutations.push_back( + mutationContainer.insertMutations.push_back( + ShadowViewMutation::InsertMutation( + parentShadowView, + newChildPair.shadowView, + static_cast(newChildPair.mountIndex))); + mutationContainer.createMutations.push_back( ShadowViewMutation::CreateMutation(newChildPair.shadowView)); ViewNodePairScope innerScope{}; @@ -1121,7 +1256,7 @@ static void calculateShadowViewMutationsV2( DIFF_BREADCRUMB( "Trivial create " + std::to_string(newChildPair.shadowView.tag)), innerScope, - downwardMutations, + mutationContainer.downwardMutations, newChildPair.shadowView, {}, sliceChildShadowNodeViewPairsFromViewNodePair( @@ -1168,160 +1303,29 @@ static void calculateShadowViewMutationsV2( << " with parent: [" << parentShadowView.tag << "]"; }); - // Check concrete-ness of views - // Create/Delete and Insert/Remove if necessary - if (oldChildPair.isConcreteView != newChildPair.isConcreteView) { - if (newChildPair.isConcreteView) { - insertMutations.push_back(ShadowViewMutation::InsertMutation( - parentShadowView, - newChildPair.shadowView, - static_cast(newChildPair.mountIndex))); - createMutations.push_back( - ShadowViewMutation::CreateMutation(newChildPair.shadowView)); - } else { - removeMutations.push_back(ShadowViewMutation::RemoveMutation( - parentShadowView, - oldChildPair.shadowView, - static_cast(oldChildPair.mountIndex))); - deleteMutations.push_back( - ShadowViewMutation::DeleteMutation(oldChildPair.shadowView)); - } - } else if ( - oldChildPair.isConcreteView && newChildPair.isConcreteView) { - // Even if node's children are flattened, it might still be a - // concrete view. The case where they're different is handled - // above. - if (oldChildPair.shadowView != newChildPair.shadowView) { - updateMutations.push_back(ShadowViewMutation::UpdateMutation( - oldChildPair.shadowView, newChildPair.shadowView)); - } - - // Remove from newRemainingPairs - auto newRemainingPairIt = newRemainingPairs.find(oldTag); - if (newRemainingPairIt != newRemainingPairs.end()) { - newRemainingPairs.erase(newRemainingPairIt); - } - } - - // Are we flattening or unflattening either one? If node was - // flattened in both trees, there's no change, just continue. - if (oldChildPair.flattened && newChildPair.flattened) { - newIndex++; - oldIndex++; - continue; - } - // We are either flattening or unflattening this node. - if (oldChildPair.flattened != newChildPair.flattened) { - DEBUG_LOGS({ - LOG(ERROR) << "Differ: flattening or unflattening at branch 6: [" - << oldChildPair.shadowView.tag << "] [" - << newChildPair.shadowView.tag << "] " - << oldChildPair.flattened << " " - << newChildPair.flattened << " with parent: [" - << parentShadowView.tag << "]"; - }); - - // Flattening - if (!oldChildPair.flattened) { - // Flatten old tree into new list - // At the end of this loop we still want to know which of these - // children are visited, so we reuse the `newRemainingPairs` - // map. - calculateShadowViewMutationsFlattener( - DIFF_BREADCRUMB( - "Flatten tree " + std::to_string(parentShadowView.tag) + - " into list " + - std::to_string(oldChildPair.shadowView.tag)), - scope, - ReparentMode::Flatten, - mutationInstructionContainer, - parentShadowView, - newRemainingPairs, - oldChildPair); - } - // Unflattening - else { - // Construct unvisited nodes map - auto unvisitedOldChildPairs = - TinyMap{}; - // We don't know where all the children of oldChildPair are - // within oldChildPairs, but we know that they're in the same - // relative order. The reason for this is because of flattening - // + zIndex: the children could be listed before the parent, - // interwoven with children from other nodes, etc. - auto oldFlattenedNodes = - sliceChildShadowNodeViewPairsFromViewNodePair( - oldChildPair, scope, true); - for (size_t i = 0, j = 0; - i < oldChildPairs.size() && j < oldFlattenedNodes.size(); - i++) { - auto &oldChild = *oldChildPairs[i]; - if (oldChild.shadowView.tag == - oldFlattenedNodes[j]->shadowView.tag) { - unvisitedOldChildPairs.insert( - {oldChild.shadowView.tag, &oldChild}); - j++; - } - } - - // Unflatten old list into new tree - calculateShadowViewMutationsFlattener( - DIFF_BREADCRUMB( - "Unflatten old list " + - std::to_string(parentShadowView.tag) + " into new tree " + - std::to_string(newChildPair.shadowView.tag)), - scope, - ReparentMode::Unflatten, - mutationInstructionContainer, - parentShadowView, - unvisitedOldChildPairs, - newChildPair); - - // If old nodes were not visited, we know that we can delete - // them now. They will be removed from the hierarchy by the - // outermost loop of this function. - for (auto &oldFlattenedNodePtr : oldFlattenedNodes) { - auto &oldFlattenedNode = *oldFlattenedNodePtr; - auto unvisitedOldChildPairIt = unvisitedOldChildPairs.find( - oldFlattenedNode.shadowView.tag); - if (unvisitedOldChildPairIt == unvisitedOldChildPairs.end()) { - // Node was visited - make sure to remove it from - // "newRemainingPairs" map - auto newRemainingIt = - newRemainingPairs.find(oldFlattenedNode.shadowView.tag); - if (newRemainingIt != newRemainingPairs.end()) { - newRemainingPairs.erase(newRemainingIt); - } - } - } - } - - newIndex++; - oldIndex++; - continue; - } + updateMatchedPair( + DIFF_BREADCRUMB( + "Update Matched Pairs (1): " + + std::to_string(oldChildPair.shadowView.tag)), + mutationContainer, + true, + true, + parentShadowView, + oldChildPair, + newChildPair); - // Update subtrees if View is not flattened, and if node addresses - // are not equal - if (oldChildPair.shadowNode != newChildPair.shadowNode) { - ViewNodePairScope innerScope{}; - auto oldGrandChildPairs = - sliceChildShadowNodeViewPairsFromViewNodePair( - oldChildPair, innerScope); - auto newGrandChildPairs = - sliceChildShadowNodeViewPairsFromViewNodePair( - newChildPair, innerScope); - calculateShadowViewMutationsV2( - DIFF_BREADCRUMB( - "Non-trivial update " + - std::to_string(oldChildPair.shadowView.tag)), - innerScope, - *(newGrandChildPairs.size() ? &downwardMutations - : &destructiveDownwardMutations), - oldChildPair.shadowView, - std::move(oldGrandChildPairs), - std::move(newGrandChildPairs)); - } + updateMatchedPairSubtrees( + DIFF_BREADCRUMB( + "Update Matched Pair Subtrees (1): " + + std::to_string(oldChildPair.shadowView.tag)), + scope, + mutationContainer, + newRemainingPairs, + oldChildPairs, + newChildPairs, + parentShadowView, + oldChildPair, + newChildPair); newIndex++; oldIndex++; @@ -1344,156 +1348,29 @@ static void calculateShadowViewMutationsV2( if (insertedIt != newInsertedPairs.end()) { auto const &newChildPair = *insertedIt->second; - // The node has been reordered and we are also flattening or - // unflattening - if (oldChildPair.flattened != newChildPair.flattened) { - DEBUG_LOGS({ - LOG(ERROR) - << "Differ: branch 7: Flattening or unflattening already-inserted node upon remove (move/reorder operation)." - << oldChildPair.shadowView.tag << " " - << oldChildPair.flattened << " // " - << newChildPair.shadowView.tag << " " - << newChildPair.flattened; - }); - - // Unflattening. - // The node in question was already inserted and we are - // *unflattening* it, so we just need to update the subtree nodes - // and remove them from the view hierarchy. Any of the unvisited - // nodes in the old tree will be deleted. - // TODO: can we consolidate this code? It's identical to the first - // block above. - if (!oldChildPair.flattened) { - // Flatten old tree into new list - // At the end of this loop we still want to know which of these - // children are visited, so we reuse the `newRemainingPairs` - // map. - calculateShadowViewMutationsFlattener( - DIFF_BREADCRUMB( - "Flatten2 " + std::to_string(parentShadowView.tag)), - scope, - ReparentMode::Flatten, - mutationInstructionContainer, - parentShadowView, - newRemainingPairs, - oldChildPair); - } - // Unflattening - else { - // Construct unvisited nodes map - auto unvisitedOldChildPairs = - TinyMap{}; - // We don't know where all the children of oldChildPair are - // within oldChildPairs, but we know that they're in the same - // relative order. The reason for this is because of flattening - // + zIndex: the children could be listed before the parent, - // interwoven with children from other nodes, etc. - auto oldFlattenedNodes = - sliceChildShadowNodeViewPairsFromViewNodePair( - oldChildPair, scope, true); - for (size_t i = 0, j = 0; - i < oldChildPairs.size() && j < oldFlattenedNodes.size(); - i++) { - auto &oldChild = *oldChildPairs[i]; - if (oldChild.shadowView.tag == - oldFlattenedNodes[j]->shadowView.tag) { - unvisitedOldChildPairs.insert( - {oldChild.shadowView.tag, &oldChild}); - j++; - } - } - - // Unflatten old list into new tree - calculateShadowViewMutationsFlattener( - DIFF_BREADCRUMB( - "Unflatten2 " + std::to_string(parentShadowView.tag)), - scope, - ReparentMode::Unflatten, - mutationInstructionContainer, - parentShadowView, - unvisitedOldChildPairs, - newChildPair); - - // If old nodes were not visited, we know that we can delete - // them now. They will be removed from the hierarchy by the - // outermost loop of this function. TODO: delete recursively? - // create recursively? - for (auto &oldFlattenedNodePtr : oldFlattenedNodes) { - auto &oldFlattenedNode = *oldFlattenedNodePtr; - auto unvisitedOldChildPairIt = unvisitedOldChildPairs.find( - oldFlattenedNode.shadowView.tag); - if (unvisitedOldChildPairIt == unvisitedOldChildPairs.end()) { - // Node was visited - make sure to remove it from - // "newRemainingPairs" map - auto newRemainingIt = - newRemainingPairs.find(oldFlattenedNode.shadowView.tag); - if (newRemainingIt != newRemainingPairs.end()) { - newRemainingPairs.erase(newRemainingIt); - } - } - } - } - } - - // Check concrete-ness of views - // Create/Delete and Insert/Remove if necessary - // TODO: document: Insert should already be handled by outermost - // loop, but not Remove - if (oldChildPair.isConcreteView != newChildPair.isConcreteView) { - if (newChildPair.isConcreteView) { - createMutations.push_back( - ShadowViewMutation::CreateMutation(newChildPair.shadowView)); - } else { - removeMutations.push_back(ShadowViewMutation::RemoveMutation( - parentShadowView, - oldChildPair.shadowView, - static_cast(oldChildPair.mountIndex))); - deleteMutations.push_back( - ShadowViewMutation::DeleteMutation(oldChildPair.shadowView)); - } - } - - // old and new child pairs are both either flattened or unflattened - // at this point. If they're not views, we don't need to update - // subtrees. - if (oldChildPair.isConcreteView && newChildPair.isConcreteView) { - // TODO: do we always want to remove here? There are cases where - // we might be able to remove this to prevent unnecessary - // removes/inserts in cases of (un)flattening + reorders? - // If removing here, we must remove the newest version of the View - // - which will always be in the "new" tree. - removeMutations.push_back(ShadowViewMutation::RemoveMutation( - parentShadowView, - newChildPair.shadowView, - static_cast(oldChildPair.mountIndex))); - - if (oldChildPair.shadowView != newChildPair.shadowView) { - updateMutations.push_back(ShadowViewMutation::UpdateMutation( - oldChildPair.shadowView, newChildPair.shadowView)); - } - } + updateMatchedPair( + DIFF_BREADCRUMB( + "Update Matched Pairs (2): " + + std::to_string(oldChildPair.shadowView.tag)), + mutationContainer, + true, + false, + parentShadowView, + oldChildPair, + newChildPair); - if (!oldChildPair.flattened && !newChildPair.flattened && - oldChildPair.shadowNode != newChildPair.shadowNode) { - // Update subtrees - ViewNodePairScope innerScope{}; - auto oldGrandChildPairs = - sliceChildShadowNodeViewPairsFromViewNodePair( - oldChildPair, innerScope); - auto newGrandChildPairs = - sliceChildShadowNodeViewPairsFromViewNodePair( - newChildPair, innerScope); - calculateShadowViewMutationsV2( - DIFF_BREADCRUMB( - "Non-trivial update3 " + - std::to_string(oldChildPair.shadowView.tag)), - innerScope, - *(newGrandChildPairs.size() ? &downwardMutations - : &destructiveDownwardMutations), - oldChildPair.shadowView, - std::move(oldGrandChildPairs), - std::move(newGrandChildPairs)); - } + updateMatchedPairSubtrees( + DIFF_BREADCRUMB( + "Update Matched Pair Subtrees (2): " + + std::to_string(oldChildPair.shadowView.tag)), + scope, + mutationContainer, + newRemainingPairs, + oldChildPairs, + newChildPairs, + parentShadowView, + oldChildPair, + newChildPair); newInsertedPairs.erase(insertedIt); oldIndex++; @@ -1543,17 +1420,19 @@ static void calculateShadowViewMutationsV2( // Here we do *not" need to generate a potential DELETE mutation // because we know the view is concrete, and still in the new // hierarchy. - removeMutations.push_back(ShadowViewMutation::RemoveMutation( - parentShadowView, - otherTreeView, - static_cast(oldChildPair.mountIndex))); + mutationContainer.removeMutations.push_back( + ShadowViewMutation::RemoveMutation( + parentShadowView, + otherTreeView, + static_cast(oldChildPair.mountIndex))); continue; } - removeMutations.push_back(ShadowViewMutation::RemoveMutation( - parentShadowView, - oldChildPair.shadowView, - static_cast(oldChildPair.mountIndex))); + mutationContainer.removeMutations.push_back( + ShadowViewMutation::RemoveMutation( + parentShadowView, + oldChildPair.shadowView, + static_cast(oldChildPair.mountIndex))); deletionCandidatePairs.insert( {oldChildPair.shadowView.tag, &oldChildPair}); @@ -1576,10 +1455,11 @@ static void calculateShadowViewMutationsV2( << " with parent: [" << parentShadowView.tag << "]"; }); if (newChildPair.isConcreteView) { - insertMutations.push_back(ShadowViewMutation::InsertMutation( - parentShadowView, - newChildPair.shadowView, - static_cast(newChildPair.mountIndex))); + mutationContainer.insertMutations.push_back( + ShadowViewMutation::InsertMutation( + parentShadowView, + newChildPair.shadowView, + static_cast(newChildPair.mountIndex))); } // `inOtherTree` is only set to true during flattening/unflattening of @@ -1620,7 +1500,7 @@ static void calculateShadowViewMutationsV2( // This can happen when the parent is unflattened if (!oldChildPair.inOtherTree() && oldChildPair.isConcreteView) { - deleteMutations.push_back( + mutationContainer.deleteMutations.push_back( ShadowViewMutation::DeleteMutation(oldChildPair.shadowView)); // We also have to call the algorithm recursively to clean up the @@ -1631,7 +1511,7 @@ static void calculateShadowViewMutationsV2( "Non-trivial delete " + std::to_string(oldChildPair.shadowView.tag)), innerScope, - destructiveDownwardMutations, + mutationContainer.destructiveDownwardMutations, oldChildPair.shadowView, sliceChildShadowNodeViewPairsFromViewNodePair( oldChildPair, innerScope), @@ -1670,7 +1550,7 @@ static void calculateShadowViewMutationsV2( continue; } - createMutations.push_back( + mutationContainer.createMutations.push_back( ShadowViewMutation::CreateMutation(newChildPair.shadowView)); ViewNodePairScope innerScope{}; @@ -1679,7 +1559,7 @@ static void calculateShadowViewMutationsV2( "Non-trivial create " + std::to_string(newChildPair.shadowView.tag)), innerScope, - downwardMutations, + mutationContainer.downwardMutations, newChildPair.shadowView, {}, sliceChildShadowNodeViewPairsFromViewNodePair( @@ -1689,32 +1569,32 @@ static void calculateShadowViewMutationsV2( // All mutations in an optimal order: std::move( - destructiveDownwardMutations.begin(), - destructiveDownwardMutations.end(), + mutationContainer.destructiveDownwardMutations.begin(), + mutationContainer.destructiveDownwardMutations.end(), std::back_inserter(mutations)); std::move( - updateMutations.begin(), - updateMutations.end(), + mutationContainer.updateMutations.begin(), + mutationContainer.updateMutations.end(), std::back_inserter(mutations)); std::move( - removeMutations.rbegin(), - removeMutations.rend(), + mutationContainer.removeMutations.rbegin(), + mutationContainer.removeMutations.rend(), std::back_inserter(mutations)); std::move( - deleteMutations.begin(), - deleteMutations.end(), + mutationContainer.deleteMutations.begin(), + mutationContainer.deleteMutations.end(), std::back_inserter(mutations)); std::move( - createMutations.begin(), - createMutations.end(), + mutationContainer.createMutations.begin(), + mutationContainer.createMutations.end(), std::back_inserter(mutations)); std::move( - downwardMutations.begin(), - downwardMutations.end(), + mutationContainer.downwardMutations.begin(), + mutationContainer.downwardMutations.end(), std::back_inserter(mutations)); std::move( - insertMutations.begin(), - insertMutations.end(), + mutationContainer.insertMutations.begin(), + mutationContainer.insertMutations.end(), std::back_inserter(mutations)); } diff --git a/ReactCommon/react/renderer/mounting/ShadowTree.cpp b/ReactCommon/react/renderer/mounting/ShadowTree.cpp index 9c165752d6d2bd..5d074d7a977e47 100644 --- a/ReactCommon/react/renderer/mounting/ShadowTree.cpp +++ b/ReactCommon/react/renderer/mounting/ShadowTree.cpp @@ -178,7 +178,7 @@ static void updateMountedFlag( return; } - int index; + size_t index; // Stage 1: Mount and unmount "updated" children. for (index = 0; index < oldChildren.size() && index < newChildren.size(); @@ -202,7 +202,7 @@ static void updateMountedFlag( updateMountedFlag(oldChild->getChildren(), newChild->getChildren()); } - int lastIndexAfterFirstStage = index; + size_t lastIndexAfterFirstStage = index; // State 2: Mount new children. for (index = lastIndexAfterFirstStage; index < newChildren.size(); index++) { diff --git a/ReactCommon/react/renderer/mounting/ShadowView.h b/ReactCommon/react/renderer/mounting/ShadowView.h index cd1e1fa040c88e..3631551ae1903f 100644 --- a/ReactCommon/react/renderer/mounting/ShadowView.h +++ b/ReactCommon/react/renderer/mounting/ShadowView.h @@ -83,7 +83,7 @@ struct ShadowViewNodePair final { * rely on this more heavily to simplify the diffing algorithm * overall? */ - ShadowViewNodePair const *otherTreePair{nullptr}; + mutable ShadowViewNodePair const *otherTreePair{nullptr}; /* * The stored pointer to `ShadowNode` represents an identity of the pair. diff --git a/ReactCommon/react/renderer/mounting/StubViewTree.cpp b/ReactCommon/react/renderer/mounting/StubViewTree.cpp index 5a9143faee1cf0..6e82ad5028fb1a 100644 --- a/ReactCommon/react/renderer/mounting/StubViewTree.cpp +++ b/ReactCommon/react/renderer/mounting/StubViewTree.cpp @@ -117,7 +117,9 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) { }); react_native_assert(childStubView->parentTag == NO_VIEW_TAG); react_native_assert( - parentStubView->children.size() >= mutation.index); + mutation.index >= 0 && + parentStubView->children.size() >= + static_cast(mutation.index)); childStubView->parentTag = parentTag; parentStubView->children.insert( parentStubView->children.begin() + mutation.index, childStubView); @@ -147,7 +149,10 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) { << parentTag << "] @" << mutation.index << " with " << parentStubView->children.size() << " children"; }); - react_native_assert(parentStubView->children.size() > mutation.index); + react_native_assert( + mutation.index >= 0 && + parentStubView->children.size() > + static_cast(mutation.index)); react_native_assert(registry.find(childTag) != registry.end()); auto childStubView = registry[childTag]; if ((ShadowView)(*childStubView) != mutation.oldChildShadowView) { @@ -183,7 +188,9 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) { << ": " << strChildList; }); react_native_assert( - parentStubView->children.size() > mutation.index && + mutation.index >= 0 && + parentStubView->children.size() > + static_cast(mutation.index) && parentStubView->children[mutation.index]->tag == childStubView->tag); childStubView->parentTag = NO_VIEW_TAG; diff --git a/ReactCommon/react/renderer/mounting/TelemetryController.cpp b/ReactCommon/react/renderer/mounting/TelemetryController.cpp index b058bebcae8ae4..a9e36d9a399637 100644 --- a/ReactCommon/react/renderer/mounting/TelemetryController.cpp +++ b/ReactCommon/react/renderer/mounting/TelemetryController.cpp @@ -30,7 +30,7 @@ bool TelemetryController::pullTransaction( auto surfaceId = transaction.getSurfaceId(); auto number = transaction.getNumber(); auto telemetry = transaction.getTelemetry(); - auto numberOfMutations = transaction.getMutations().size(); + auto numberOfMutations = static_cast(transaction.getMutations().size()); mutex_.lock(); auto compoundTelemetry = compoundTelemetry_; diff --git a/ReactCommon/react/renderer/mounting/stubs.cpp b/ReactCommon/react/renderer/mounting/stubs.cpp index c9c1709b71e7e1..02fb98597c1aac 100644 --- a/ReactCommon/react/renderer/mounting/stubs.cpp +++ b/ReactCommon/react/renderer/mounting/stubs.cpp @@ -47,13 +47,13 @@ static void calculateShadowViewMutationsForNewTree( // Sorting pairs based on `orderIndex` if needed. reorderInPlaceIfNeeded(newChildPairs); - for (auto index = 0; index < newChildPairs.size(); index++) { + for (size_t index = 0; index < newChildPairs.size(); index++) { auto const &newChildPair = newChildPairs[index]; mutations.push_back( ShadowViewMutation::CreateMutation(newChildPair.shadowView)); mutations.push_back(ShadowViewMutation::InsertMutation( - parentShadowView, newChildPair.shadowView, index)); + parentShadowView, newChildPair.shadowView, static_cast(index))); auto newGrandChildPairs = sliceChildShadowNodeViewPairsLegacy(*newChildPair.shadowNode); diff --git a/ReactCommon/react/renderer/mounting/tests/MountingTest.cpp b/ReactCommon/react/renderer/mounting/tests/MountingTest.cpp index 0cb2fb47409b82..6c407f15f42e05 100644 --- a/ReactCommon/react/renderer/mounting/tests/MountingTest.cpp +++ b/ReactCommon/react/renderer/mounting/tests/MountingTest.cpp @@ -12,7 +12,7 @@ #include #include -#include "shadowTreeGeneration.h" +#include #include #include diff --git a/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp b/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp index 1362d2ee65ac0f..813dadb1e17d67 100644 --- a/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp +++ b/ReactCommon/react/renderer/mounting/tests/ShadowTreeLifeCycleTest.cpp @@ -16,8 +16,12 @@ #include #include -#include "Entropy.h" -#include "shadowTreeGeneration.h" +#include +#include + +// Uncomment when random test blocks are uncommented below. +// #include +// #include namespace facebook { namespace react { @@ -121,7 +125,7 @@ static void testShadowNodeTreeLifeCycle( mutation.newChildShadowView.tag) != deletedTags.end()) { LOG(ERROR) << "Deleted tag was recreated in mutations list: [" << mutation.newChildShadowView.tag << "]"; - FAIL(); + react_native_assert(false); } } } @@ -159,7 +163,7 @@ static void testShadowNodeTreeLifeCycle( << getDebugDescription(mutations, {}); #endif - FAIL(); + react_native_assert(false); } currentRootNode = nextRootNode; @@ -269,7 +273,7 @@ static void testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening( mutation.newChildShadowView.tag) != deletedTags.end()) { LOG(ERROR) << "Deleted tag was recreated in mutations list: [" << mutation.newChildShadowView.tag << "]"; - FAIL(); + react_native_assert(false); } } } @@ -307,7 +311,7 @@ static void testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening( << getDebugDescription(mutations, {}); #endif - FAIL(); + react_native_assert(false); } currentRootNode = nextRootNode; @@ -381,3 +385,31 @@ TEST( /* repeats */ 512, /* stages */ 32); } + +// failing test case found 4-25-2021 +TEST( + ShadowTreeLifecyleTest, + unstableSmallerTreeMoreIterationsExtensiveFlatteningUnflattening_1167342011) { + testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening( + /* seed */ 1167342011, + /* size */ 32, + /* repeats */ 512, + /* stages */ 32); +} + +// You may uncomment this - locally only! - to generate failing seeds. +// TEST( +// ShadowTreeLifecyleTest, +// unstableSmallerTreeMoreIterationsExtensiveFlatteningUnflatteningManyRandom) +// { +// std::random_device device; +// for (int i = 0; i < 10; i++) { +// uint_fast32_t seed = device(); +// LOG(ERROR) << "Seed: " << seed; +// testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening( +// /* seed */ seed, +// /* size */ 32, +// /* repeats */ 512, +// /* stages */ 32); +// } +// } diff --git a/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp b/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp index 88c04c7831811a..d5ddc44c3f4d0f 100644 --- a/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp +++ b/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp @@ -9,14 +9,30 @@ namespace facebook::react { -RuntimeScheduler::RuntimeScheduler(RuntimeExecutor const &runtimeExecutor) - : RuntimeScheduler(runtimeExecutor, RuntimeSchedulerClock::now) {} +#pragma mark - Public RuntimeScheduler::RuntimeScheduler( RuntimeExecutor const &runtimeExecutor, std::function now) : runtimeExecutor_(runtimeExecutor), now_(now) {} +void RuntimeScheduler::scheduleWork( + std::function callback) const { + if (enableYielding_) { + shouldYield_ = true; + runtimeExecutor_( + [this, callback = std::move(callback)](jsi::Runtime &runtime) { + shouldYield_ = false; + callback(runtime); + startWorkLoop(runtime); + }); + } else { + runtimeExecutor_([callback = std::move(callback)](jsi::Runtime &runtime) { + callback(runtime); + }); + } +} + std::shared_ptr RuntimeScheduler::scheduleTask( SchedulerPriority priority, jsi::Function callback) { @@ -29,28 +45,68 @@ std::shared_ptr RuntimeScheduler::scheduleTask( isCallbackScheduled_ = true; runtimeExecutor_([this](jsi::Runtime &runtime) { isCallbackScheduled_ = false; - - while (!taskQueue_.empty()) { - auto topPriority = taskQueue_.top(); - taskQueue_.pop(); - (*topPriority)(runtime); - } + startWorkLoop(runtime); }); } return task; } +bool RuntimeScheduler::getShouldYield() const { + return shouldYield_; +} + void RuntimeScheduler::cancelTask(const std::shared_ptr &task) { - task->cancel(); + task->callback.reset(); } -bool RuntimeScheduler::getShouldYield() const { - return shouldYield_; +SchedulerPriority RuntimeScheduler::getCurrentPriorityLevel() const { + return currentPriority_; } RuntimeSchedulerTimePoint RuntimeScheduler::now() const { return now_(); } +void RuntimeScheduler::setEnableYielding(bool enableYielding) { + enableYielding_ = enableYielding; +} + +void RuntimeScheduler::executeNowOnTheSameThread( + std::function callback) const { + shouldYield_ = true; + executeSynchronouslyOnSameThread_CAN_DEADLOCK( + runtimeExecutor_, + [callback = std::move(callback)](jsi::Runtime &runtime) { + callback(runtime); + }); + shouldYield_ = false; +} + +#pragma mark - Private + +void RuntimeScheduler::startWorkLoop(jsi::Runtime &runtime) const { + auto previousPriority = currentPriority_; + while (!taskQueue_.empty()) { + auto topPriorityTask = taskQueue_.top(); + auto now = now_(); + auto didUserCallbackTimeout = topPriorityTask->expirationTime <= now; + + if (!didUserCallbackTimeout && shouldYield_) { + // This task hasn't expired and we need to yield. + break; + } + currentPriority_ = topPriorityTask->priority; + auto result = topPriorityTask->execute(runtime); + + if (result.isObject() && result.getObject(runtime).isFunction(runtime)) { + topPriorityTask->callback = + result.getObject(runtime).getFunction(runtime); + } else { + taskQueue_.pop(); + } + } + currentPriority_ = previousPriority; +} + } // namespace facebook::react diff --git a/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h b/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h index ec7d0455a79fb3..013079a62b353d 100644 --- a/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h +++ b/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h @@ -18,10 +18,22 @@ namespace facebook::react { class RuntimeScheduler final { public: - RuntimeScheduler(RuntimeExecutor const &runtimeExecutor); RuntimeScheduler( RuntimeExecutor const &runtimeExecutor, - std::function now); + std::function now = + RuntimeSchedulerClock::now); + + void scheduleWork(std::function callback) const; + + /* + * Grants access to the runtime synchronously on the caller's thread. + * + * Shouldn't be called directly. it is expected to be used + * by dispatching a synchronous event via event emitter in your native + * component. + */ + void executeNowOnTheSameThread( + std::function callback) const; std::shared_ptr scheduleTask( SchedulerPriority priority, @@ -31,16 +43,29 @@ class RuntimeScheduler final { bool getShouldYield() const; + SchedulerPriority getCurrentPriorityLevel() const; + RuntimeSchedulerTimePoint now() const; + void setEnableYielding(bool enableYielding); + private: mutable std::priority_queue< std::shared_ptr, std::vector>, TaskPriorityComparer> taskQueue_; + RuntimeExecutor const runtimeExecutor_; - std::atomic_bool shouldYield_{false}; + mutable SchedulerPriority currentPriority_{SchedulerPriority::NormalPriority}; + mutable std::atomic_bool shouldYield_{false}; + + void startWorkLoop(jsi::Runtime &runtime) const; + + /* + * Returns a time point representing the current point in time. May be called + * from multiple threads. + */ std::function now_; /* @@ -48,6 +73,15 @@ class RuntimeScheduler final { * scheduled. */ std::atomic_bool isCallbackScheduled_{false}; + + /* + * Flag indicating if yielding is enabled. + * + * If set to true and Concurrent Mode is enabled on the surface, + * React Native will ask React to yield in case any work has been scheduled. + * Default value is false + */ + bool enableYielding_{false}; }; } // namespace facebook::react diff --git a/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp b/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp index 9ceebc0e1f429a..4d5a19f8bb55e7 100644 --- a/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp +++ b/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp @@ -18,7 +18,7 @@ namespace facebook::react { std::shared_ptr RuntimeSchedulerBinding::createAndInstallIfNeeded( jsi::Runtime &runtime, - RuntimeExecutor runtimeExecutor) { + std::shared_ptr const &runtimeScheduler) { auto runtimeSchedulerModuleName = "nativeRuntimeScheduler"; auto runtimeSchedulerValue = @@ -26,9 +26,8 @@ RuntimeSchedulerBinding::createAndInstallIfNeeded( if (runtimeSchedulerValue.isUndefined()) { // The global namespace does not have an instance of the binding; // we need to create, install and return it. - auto runtimeScheduler = std::make_unique(runtimeExecutor); auto runtimeSchedulerBinding = - std::make_shared(std::move(runtimeScheduler)); + std::make_shared(runtimeScheduler); auto object = jsi::Object::createFromHostObject(runtime, runtimeSchedulerBinding); runtime.global().setProperty( @@ -43,8 +42,8 @@ RuntimeSchedulerBinding::createAndInstallIfNeeded( } RuntimeSchedulerBinding::RuntimeSchedulerBinding( - std::unique_ptr runtimeScheduler) - : runtimeScheduler_(std::move(runtimeScheduler)) {} + std::shared_ptr const &runtimeScheduler) + : runtimeScheduler_(runtimeScheduler) {} jsi::Value RuntimeSchedulerBinding::get( jsi::Runtime &runtime, @@ -133,6 +132,11 @@ jsi::Value RuntimeSchedulerBinding::get( }); } + if (propertyName == "unstable_getCurrentPriorityLevel") { + auto currentPriorityLevel = runtimeScheduler_->getCurrentPriorityLevel(); + return jsi::Value(runtime, serialize(currentPriorityLevel)); + } + if (propertyName == "unstable_ImmediatePriority") { return jsi::Value(runtime, serialize(SchedulerPriority::ImmediatePriority)); } @@ -154,6 +158,10 @@ jsi::Value RuntimeSchedulerBinding::get( return jsi::Value(runtime, serialize(SchedulerPriority::IdlePriority)); } + if (propertyName == "$$typeof") { + return jsi::Value::undefined(); + } + react_native_assert(false && "undefined property"); return jsi::Value::undefined(); } diff --git a/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h b/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h index 92bb5780e84d79..cc4544d6a8f17b 100644 --- a/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h +++ b/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h @@ -17,7 +17,8 @@ namespace facebook::react { */ class RuntimeSchedulerBinding : public jsi::HostObject { public: - RuntimeSchedulerBinding(std::unique_ptr runtimeScheduler); + RuntimeSchedulerBinding( + std::shared_ptr const &runtimeScheduler); /* * Installs RuntimeSchedulerBinding into JavaScript runtime if needed. @@ -27,7 +28,7 @@ class RuntimeSchedulerBinding : public jsi::HostObject { */ static std::shared_ptr createAndInstallIfNeeded( jsi::Runtime &runtime, - RuntimeExecutor runtimeExecutor); + std::shared_ptr const &runtimeScheduler); /* * `jsi::HostObject` specific overloads. @@ -35,7 +36,7 @@ class RuntimeSchedulerBinding : public jsi::HostObject { jsi::Value get(jsi::Runtime &runtime, jsi::PropNameID const &name) override; private: - std::unique_ptr runtimeScheduler_; + std::shared_ptr runtimeScheduler_; }; } // namespace facebook::react diff --git a/ReactCommon/react/renderer/runtimescheduler/Task.cpp b/ReactCommon/react/renderer/runtimescheduler/Task.cpp index 0316fa00ddfeae..c0d9b2f1671e16 100644 --- a/ReactCommon/react/renderer/runtimescheduler/Task.cpp +++ b/ReactCommon/react/renderer/runtimescheduler/Task.cpp @@ -13,30 +13,19 @@ Task::Task( SchedulerPriority priority, jsi::Function callback, std::chrono::steady_clock::time_point expirationTime) - : priority_(priority), - callback_(std::move(callback)), - expirationTime_(expirationTime) {} - -SchedulerPriority Task::getPriority() const { - return priority_; -} - -RuntimeSchedulerClock::time_point Task::getExpirationTime() const { - return expirationTime_; -} - -void Task::cancel() { - // Null out the callback to indicate the task has been canceled. (Can't - // remove from the priority_queue because you can't remove arbitrary nodes - // from an array based heap, only the first one.) - callback_.reset(); -} - -void Task::operator()(jsi::Runtime &runtime) const { - if (callback_) { - // Cancelled task doesn't have a callback. - callback_.value().call(runtime, {}); + : priority(priority), + callback(std::move(callback)), + expirationTime(expirationTime) {} + +jsi::Value Task::execute(jsi::Runtime &runtime) const { + // Cancelled task doesn't have a callback. + if (callback) { + // Callback in JavaScript is expecting a single bool parameter. + // React team plans to remove it and it is safe to pass in + // hardcoded false value. + return callback.value().call(runtime, {false}); } + return jsi::Value::undefined(); } } // namespace facebook::react diff --git a/ReactCommon/react/renderer/runtimescheduler/Task.h b/ReactCommon/react/renderer/runtimescheduler/Task.h index 2c750d7af4d925..0d97ea8e80b2f9 100644 --- a/ReactCommon/react/renderer/runtimescheduler/Task.h +++ b/ReactCommon/react/renderer/runtimescheduler/Task.h @@ -14,25 +14,24 @@ namespace facebook::react { -class Task final { - public: +class RuntimeScheduler; +class TaskPriorityComparer; + +struct Task final { Task( SchedulerPriority priority, jsi::Function callback, std::chrono::steady_clock::time_point expirationTime); - SchedulerPriority getPriority() const; - - RuntimeSchedulerClock::time_point getExpirationTime() const; - - void cancel(); + private: + friend RuntimeScheduler; + friend TaskPriorityComparer; - void operator()(jsi::Runtime &runtime) const; + SchedulerPriority priority; + better::optional callback; + RuntimeSchedulerClock::time_point expirationTime; - private: - SchedulerPriority priority_; - better::optional callback_; - RuntimeSchedulerClock::time_point expirationTime_; + jsi::Value execute(jsi::Runtime &runtime) const; }; class TaskPriorityComparer { @@ -40,7 +39,7 @@ class TaskPriorityComparer { inline bool operator()( std::shared_ptr const &lhs, std::shared_ptr const &rhs) { - return lhs->getExpirationTime() > rhs->getExpirationTime(); + return lhs->expirationTime > rhs->expirationTime; } }; diff --git a/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp b/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp index 50e23594e0f465..c2cea4564eaed1 100644 --- a/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp +++ b/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp @@ -42,7 +42,8 @@ class RuntimeSchedulerTest : public testing::Test { std::make_unique(runtimeExecutor, stubNow); } - jsi::Function createHostFunctionFromLambda(std::function callback) { + jsi::Function createHostFunctionFromLambda( + std::function callback) { return jsi::Function::createFromHostFunction( *runtime_, jsi::PropNameID::forUtf8(*runtime_, ""), @@ -50,11 +51,11 @@ class RuntimeSchedulerTest : public testing::Test { [this, callback = std::move(callback)]( jsi::Runtime &, jsi::Value const &, - jsi::Value const *, + jsi::Value const *arguments, size_t) noexcept -> jsi::Value { ++hostFunctionCallCount_; - callback(); - return jsi::Value::undefined(); + auto didUserCallbackTimeout = arguments[0].getBool(); + return callback(didUserCallbackTimeout); }); } @@ -88,7 +89,11 @@ TEST_F(RuntimeSchedulerTest, getShouldYield) { TEST_F(RuntimeSchedulerTest, scheduleSingleTask) { bool didRunTask = false; auto callback = - createHostFunctionFromLambda([&didRunTask]() { didRunTask = true; }); + createHostFunctionFromLambda([&didRunTask](bool didUserCallbackTimeout) { + didRunTask = true; + EXPECT_FALSE(didUserCallbackTimeout); + return jsi::Value::undefined(); + }); runtimeScheduler_->scheduleTask( SchedulerPriority::NormalPriority, std::move(callback)); @@ -102,11 +107,59 @@ TEST_F(RuntimeSchedulerTest, scheduleSingleTask) { EXPECT_EQ(stubQueue_->size(), 0); } +TEST_F(RuntimeSchedulerTest, scheduleImmediatePriorityTask) { + bool didRunTask = false; + auto callback = + createHostFunctionFromLambda([&didRunTask](bool didUserCallbackTimeout) { + didRunTask = true; + EXPECT_FALSE(didUserCallbackTimeout); + return jsi::Value::undefined(); + }); + + runtimeScheduler_->scheduleTask( + SchedulerPriority::ImmediatePriority, std::move(callback)); + + EXPECT_FALSE(didRunTask); + EXPECT_EQ(stubQueue_->size(), 1); + + stubQueue_->tick(); + + EXPECT_TRUE(didRunTask); + EXPECT_EQ(stubQueue_->size(), 0); +} + +TEST_F(RuntimeSchedulerTest, taskExpiration) { + bool didRunTask = false; + auto callback = + createHostFunctionFromLambda([&didRunTask](bool didUserCallbackTimeout) { + didRunTask = true; + // Task has timed out but the parameter is deprecated and `false` is + // hardcoded. + EXPECT_FALSE(didUserCallbackTimeout); + return jsi::Value::undefined(); + }); + + runtimeScheduler_->scheduleTask( + SchedulerPriority::NormalPriority, std::move(callback)); + + // Task with normal priority has 5s timeout. + stubClock_->advanceTimeBy(6s); + + EXPECT_FALSE(didRunTask); + EXPECT_EQ(stubQueue_->size(), 1); + + stubQueue_->tick(); + + EXPECT_TRUE(didRunTask); + EXPECT_EQ(stubQueue_->size(), 0); +} + TEST_F(RuntimeSchedulerTest, scheduleTwoTasksWithSamePriority) { uint firstTaskCallOrder; auto callbackOne = - createHostFunctionFromLambda([this, &firstTaskCallOrder]() { + createHostFunctionFromLambda([this, &firstTaskCallOrder](bool) { firstTaskCallOrder = hostFunctionCallCount_; + return jsi::Value::undefined(); }); runtimeScheduler_->scheduleTask( @@ -114,8 +167,9 @@ TEST_F(RuntimeSchedulerTest, scheduleTwoTasksWithSamePriority) { uint secondTaskCallOrder; auto callbackTwo = - createHostFunctionFromLambda([this, &secondTaskCallOrder]() { + createHostFunctionFromLambda([this, &secondTaskCallOrder](bool) { secondTaskCallOrder = hostFunctionCallCount_; + return jsi::Value::undefined(); }); runtimeScheduler_->scheduleTask( @@ -136,8 +190,9 @@ TEST_F(RuntimeSchedulerTest, scheduleTwoTasksWithSamePriority) { TEST_F(RuntimeSchedulerTest, scheduleTwoTasksWithDifferentPriorities) { uint lowPriorityTaskCallOrder; auto callbackOne = - createHostFunctionFromLambda([this, &lowPriorityTaskCallOrder]() { + createHostFunctionFromLambda([this, &lowPriorityTaskCallOrder](bool) { lowPriorityTaskCallOrder = hostFunctionCallCount_; + return jsi::Value::undefined(); }); runtimeScheduler_->scheduleTask( @@ -145,8 +200,9 @@ TEST_F(RuntimeSchedulerTest, scheduleTwoTasksWithDifferentPriorities) { uint userBlockingPriorityTaskCallOrder; auto callbackTwo = createHostFunctionFromLambda( - [this, &userBlockingPriorityTaskCallOrder]() { + [this, &userBlockingPriorityTaskCallOrder](bool) { userBlockingPriorityTaskCallOrder = hostFunctionCallCount_; + return jsi::Value::undefined(); }); runtimeScheduler_->scheduleTask( @@ -166,8 +222,10 @@ TEST_F(RuntimeSchedulerTest, scheduleTwoTasksWithDifferentPriorities) { TEST_F(RuntimeSchedulerTest, cancelTask) { bool didRunTask = false; - auto callback = - createHostFunctionFromLambda([&didRunTask]() { didRunTask = true; }); + auto callback = createHostFunctionFromLambda([&didRunTask](bool) { + didRunTask = true; + return jsi::Value::undefined(); + }); auto task = runtimeScheduler_->scheduleTask( SchedulerPriority::NormalPriority, std::move(callback)); @@ -183,4 +241,198 @@ TEST_F(RuntimeSchedulerTest, cancelTask) { EXPECT_EQ(stubQueue_->size(), 0); } +TEST_F(RuntimeSchedulerTest, continuationTask) { + bool didRunTask = false; + bool didContinuationTask = false; + + auto callback = createHostFunctionFromLambda([&](bool) { + didRunTask = true; + return jsi::Function::createFromHostFunction( + *runtime_, + jsi::PropNameID::forUtf8(*runtime_, ""), + 1, + [&](jsi::Runtime &runtime, + jsi::Value const &, + jsi::Value const *arguments, + size_t) noexcept -> jsi::Value { + didContinuationTask = true; + return jsi::Value::undefined(); + }); + }); + + auto task = runtimeScheduler_->scheduleTask( + SchedulerPriority::NormalPriority, std::move(callback)); + + EXPECT_FALSE(didRunTask); + EXPECT_EQ(stubQueue_->size(), 1); + + stubQueue_->tick(); + + EXPECT_TRUE(didRunTask); + EXPECT_TRUE(didContinuationTask); + EXPECT_EQ(stubQueue_->size(), 0); +} + +TEST_F(RuntimeSchedulerTest, getCurrentPriorityLevel) { + auto callback = + createHostFunctionFromLambda([this](bool didUserCallbackTimeout) { + EXPECT_EQ( + runtimeScheduler_->getCurrentPriorityLevel(), + SchedulerPriority::ImmediatePriority); + return jsi::Value::undefined(); + }); + + EXPECT_EQ( + runtimeScheduler_->getCurrentPriorityLevel(), + SchedulerPriority::NormalPriority); + + runtimeScheduler_->scheduleTask( + SchedulerPriority::ImmediatePriority, std::move(callback)); + + stubQueue_->tick(); + + EXPECT_EQ( + runtimeScheduler_->getCurrentPriorityLevel(), + SchedulerPriority::NormalPriority); + + callback = createHostFunctionFromLambda([this](bool didUserCallbackTimeout) { + EXPECT_EQ( + runtimeScheduler_->getCurrentPriorityLevel(), + SchedulerPriority::IdlePriority); + return jsi::Value::undefined(); + }); + + runtimeScheduler_->scheduleTask( + SchedulerPriority::IdlePriority, std::move(callback)); + + stubQueue_->tick(); + + EXPECT_EQ( + runtimeScheduler_->getCurrentPriorityLevel(), + SchedulerPriority::NormalPriority); +} + +TEST_F(RuntimeSchedulerTest, scheduleWork) { + bool wasCalled = false; + runtimeScheduler_->scheduleWork( + [&](jsi::Runtime const &) { wasCalled = true; }); + + EXPECT_FALSE(wasCalled); + + EXPECT_FALSE(runtimeScheduler_->getShouldYield()); + + EXPECT_EQ(stubQueue_->size(), 1); + + stubQueue_->tick(); + + EXPECT_TRUE(wasCalled); + EXPECT_EQ(stubQueue_->size(), 0); +} + +TEST_F(RuntimeSchedulerTest, scheduleWorkWithYielding) { + runtimeScheduler_->setEnableYielding(true); + bool wasCalled = false; + runtimeScheduler_->scheduleWork( + [&](jsi::Runtime const &) { wasCalled = true; }); + + EXPECT_FALSE(wasCalled); + + EXPECT_TRUE(runtimeScheduler_->getShouldYield()); + + EXPECT_EQ(stubQueue_->size(), 1); + + stubQueue_->tick(); + + EXPECT_TRUE(wasCalled); + EXPECT_FALSE(runtimeScheduler_->getShouldYield()); + EXPECT_EQ(stubQueue_->size(), 0); +} + +TEST_F(RuntimeSchedulerTest, normalTaskYieldsToPlatformEvent) { + runtimeScheduler_->setEnableYielding(true); + + bool didRunJavaScriptTask = false; + bool didRunPlatformWork = false; + + auto callback = createHostFunctionFromLambda([&](bool) { + didRunJavaScriptTask = true; + EXPECT_TRUE(didRunPlatformWork); + return jsi::Value::undefined(); + }); + + runtimeScheduler_->scheduleTask( + SchedulerPriority::NormalPriority, std::move(callback)); + + runtimeScheduler_->scheduleWork([&](jsi::Runtime const &) { + didRunPlatformWork = true; + EXPECT_FALSE(didRunJavaScriptTask); + EXPECT_FALSE(runtimeScheduler_->getShouldYield()); + }); + + EXPECT_TRUE(runtimeScheduler_->getShouldYield()); + EXPECT_EQ(stubQueue_->size(), 2); + + stubQueue_->flush(); + + EXPECT_EQ(stubQueue_->size(), 0); +} + +TEST_F(RuntimeSchedulerTest, expiredTaskDoesntYieldToPlatformEvent) { + runtimeScheduler_->setEnableYielding(true); + + bool didRunJavaScriptTask = false; + bool didRunPlatformWork = false; + + auto callback = createHostFunctionFromLambda([&](bool) { + didRunJavaScriptTask = true; + EXPECT_FALSE(didRunPlatformWork); + return jsi::Value::undefined(); + }); + + runtimeScheduler_->scheduleTask( + SchedulerPriority::NormalPriority, std::move(callback)); + + runtimeScheduler_->scheduleWork([&](jsi::Runtime const &) { + didRunPlatformWork = true; + EXPECT_TRUE(didRunJavaScriptTask); + }); + + EXPECT_TRUE(runtimeScheduler_->getShouldYield()); + EXPECT_EQ(stubQueue_->size(), 2); + + stubClock_->advanceTimeBy(6s); + + stubQueue_->flush(); + + EXPECT_EQ(stubQueue_->size(), 0); +} + +TEST_F(RuntimeSchedulerTest, immediateTaskDoesntYieldToPlatformEvent) { + runtimeScheduler_->setEnableYielding(true); + + bool didRunJavaScriptTask = false; + bool didRunPlatformWork = false; + + auto callback = createHostFunctionFromLambda([&](bool) { + didRunJavaScriptTask = true; + EXPECT_FALSE(didRunPlatformWork); + return jsi::Value::undefined(); + }); + + runtimeScheduler_->scheduleTask( + SchedulerPriority::ImmediatePriority, std::move(callback)); + + runtimeScheduler_->scheduleWork([&](jsi::Runtime const &) { + didRunPlatformWork = true; + EXPECT_TRUE(didRunJavaScriptTask); + }); + + EXPECT_TRUE(runtimeScheduler_->getShouldYield()); + EXPECT_EQ(stubQueue_->size(), 2); + + stubQueue_->flush(); + + EXPECT_EQ(stubQueue_->size(), 0); +} + } // namespace facebook::react diff --git a/ReactCommon/react/renderer/runtimescheduler/tests/StubQueue.h b/ReactCommon/react/renderer/runtimescheduler/tests/StubQueue.h index 390963f9e9b4b0..272be4833b0069 100644 --- a/ReactCommon/react/renderer/runtimescheduler/tests/StubQueue.h +++ b/ReactCommon/react/renderer/runtimescheduler/tests/StubQueue.h @@ -15,6 +15,12 @@ class StubQueue { callbackQueue_.push(func); } + void flush() { + while (!callbackQueue_.empty()) { + tick(); + } + } + void tick() { if (!callbackQueue_.empty()) { auto callback = callbackQueue_.front(); diff --git a/ReactCommon/react/renderer/scheduler/AsynchronousEventBeatV2.cpp b/ReactCommon/react/renderer/scheduler/AsynchronousEventBeatV2.cpp new file mode 100644 index 00000000000000..68f80973e5d7a2 --- /dev/null +++ b/ReactCommon/react/renderer/scheduler/AsynchronousEventBeatV2.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "AsynchronousEventBeatV2.h" + +#include + +namespace facebook::react { + +AsynchronousEventBeatV2::AsynchronousEventBeatV2( + RunLoopObserver::Unique uiRunLoopObserver, + RuntimeExecutor runtimeExecutor) + : EventBeat({}), + uiRunLoopObserver_(std::move(uiRunLoopObserver)), + runtimeExecutor_(std::move(runtimeExecutor)) { + uiRunLoopObserver_->setDelegate(this); + uiRunLoopObserver_->enable(); +} + +void AsynchronousEventBeatV2::activityDidChange( + RunLoopObserver::Delegate const *delegate, + RunLoopObserver::Activity) const noexcept { + react_native_assert(delegate == this); + induce(); +} + +void AsynchronousEventBeatV2::induce() const { + if (!isRequested_ || isBeatCallbackScheduled_) { + return; + } + + isRequested_ = false; + + // Here we know that `this` object exists because the caller has a strong + // pointer to `owner`. To ensure the object will exist inside + // `runtimeExecutor_` callback, we need to copy the pointer there. + auto weakOwner = uiRunLoopObserver_->getOwner(); + + isBeatCallbackScheduled_ = true; + + runtimeExecutor_([this, weakOwner](jsi::Runtime &runtime) { + isBeatCallbackScheduled_ = false; + + auto owner = weakOwner.lock(); + if (!owner) { + return; + } + + if (beatCallback_) { + beatCallback_(runtime); + } + }); +} +} // namespace facebook::react diff --git a/ReactCommon/react/renderer/scheduler/AsynchronousEventBeatV2.h b/ReactCommon/react/renderer/scheduler/AsynchronousEventBeatV2.h new file mode 100644 index 00000000000000..b0449fd8d6581e --- /dev/null +++ b/ReactCommon/react/renderer/scheduler/AsynchronousEventBeatV2.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include + +namespace facebook::react { + +/* + * Event beat associated with JavaScript runtime. + * The beat is called on `RuntimeExecutor`'s thread induced by the UI thread + * event loop. + */ +class AsynchronousEventBeatV2 : public EventBeat, + public RunLoopObserver::Delegate { + public: + AsynchronousEventBeatV2( + RunLoopObserver::Unique uiRunLoopObserver, + RuntimeExecutor runtimeExecutor); + + void induce() const override; + +#pragma mark - RunLoopObserver::Delegate + + void activityDidChange( + RunLoopObserver::Delegate const *delegate, + RunLoopObserver::Activity activity) const noexcept override; + + private: + RunLoopObserver::Unique uiRunLoopObserver_; + RuntimeExecutor runtimeExecutor_; + + mutable std::atomic isBeatCallbackScheduled_{false}; +}; + +} // namespace facebook::react diff --git a/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/ReactCommon/react/renderer/scheduler/Scheduler.cpp index d6e12dbae5ddc3..d5c9ce8efd4b94 100644 --- a/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -45,9 +46,7 @@ Scheduler::Scheduler( std::make_shared>(); auto uiManager = std::make_shared( - runtimeExecutor_, - schedulerToolbox.backgroundExecutor, - schedulerToolbox.garbageCollectionTrigger); + runtimeExecutor_, schedulerToolbox.backgroundExecutor); auto eventOwnerBox = std::make_shared(); eventOwnerBox->owner = eventDispatcher_; @@ -55,11 +54,12 @@ Scheduler::Scheduler( jsi::Runtime &runtime, const EventTarget *eventTarget, const std::string &type, + ReactEventPriority priority, const ValueFactory &payloadFactory) { uiManager->visitBinding( [&](UIManagerBinding const &uiManagerBinding) { uiManagerBinding.dispatchEvent( - runtime, eventTarget, type, payloadFactory); + runtime, eventTarget, type, priority, payloadFactory); }, runtime); }; @@ -68,14 +68,22 @@ Scheduler::Scheduler( uiManager->updateState(stateUpdate); }; +#ifdef ANDROID + auto unbatchedQueuesOnly = + reactNativeConfig_->getBool("react_fabric:unbatched_queues_only_android"); +#else + auto unbatchedQueuesOnly = + reactNativeConfig_->getBool("react_fabric:unbatched_queues_only_ios"); +#endif + // Creating an `EventDispatcher` instance inside the already allocated // container (inside the optional). eventDispatcher_->emplace( - eventPipe, - statePipe, + EventQueueProcessor(eventPipe, statePipe), schedulerToolbox.synchronousEventBeatFactory, schedulerToolbox.asynchronousEventBeatFactory, - eventOwnerBox); + eventOwnerBox, + unbatchedQueuesOnly); // Casting to `std::shared_ptr`. auto eventDispatcher = @@ -87,20 +95,14 @@ Scheduler::Scheduler( uiManager->setDelegate(this); uiManager->setComponentDescriptorRegistry(componentDescriptorRegistry_); -#ifdef ANDROID - auto enableRuntimeScheduler = reactNativeConfig_->getBool( - "react_fabric:enable_runtime_scheduler_android"); -#else - auto enableRuntimeScheduler = - reactNativeConfig_->getBool("react_fabric:enable_runtime_scheduler_ios"); -#endif - - runtimeExecutor_([=](jsi::Runtime &runtime) { + runtimeExecutor_([uiManager, + runtimeScheduler = schedulerToolbox.runtimeScheduler]( + jsi::Runtime &runtime) { auto uiManagerBinding = UIManagerBinding::createAndInstallIfNeeded(runtime); uiManagerBinding->attach(uiManager); - if (enableRuntimeScheduler) { + if (runtimeScheduler) { RuntimeSchedulerBinding::createAndInstallIfNeeded( - runtime, runtimeExecutor_); + runtime, runtimeScheduler); } }); @@ -136,12 +138,8 @@ Scheduler::Scheduler( #else removeOutstandingSurfacesOnDestruction_ = reactNativeConfig_->getBool( "react_fabric:remove_outstanding_surfaces_on_destruction_ios"); - enableNewDiffer_ = - reactNativeConfig_->getBool("react_fabric:enable_new_differ_h1_2021_ios"); + enableNewDiffer_ = true; #endif - - uiManager->extractUIManagerBindingOnDemand_ = reactNativeConfig_->getBool( - "react_fabric:extract_uimanagerbinding_on_demand"); } Scheduler::~Scheduler() { diff --git a/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h b/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h index 9856cef3a36ec1..a4d8ddabdd684e 100644 --- a/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h +++ b/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,8 @@ struct SchedulerToolbox final { */ RuntimeExecutor runtimeExecutor; + std::shared_ptr runtimeScheduler; + /* * Represent connections with a platform-specific UI run loops. */ @@ -65,12 +68,6 @@ struct SchedulerToolbox final { */ BackgroundExecutor backgroundExecutor; - /* - * Triggers garbage collection. Used when checking if all Fabric's HostObjects - * have been properly cleaned up from JavaScript. - */ - GarbageCollectionTrigger garbageCollectionTrigger; - /* * A list of `UIManagerCommitHook`s that should be registered in `UIManager`. */ diff --git a/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.cpp b/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.cpp index f80fd16d11273a..66d6c8c8a0f5f0 100644 --- a/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.cpp +++ b/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.cpp @@ -14,10 +14,12 @@ namespace react { SynchronousEventBeat::SynchronousEventBeat( RunLoopObserver::Unique uiRunLoopObserver, - RuntimeExecutor runtimeExecutor) + RuntimeExecutor runtimeExecutor, + std::shared_ptr const &runtimeScheduler) : EventBeat({}), uiRunLoopObserver_(std::move(uiRunLoopObserver)), - runtimeExecutor_(std::move(runtimeExecutor)) { + runtimeExecutor_(std::move(runtimeExecutor)), + runtimeScheduler_(runtimeScheduler) { uiRunLoopObserver_->setDelegate(this); uiRunLoopObserver_->enable(); } @@ -44,8 +46,13 @@ void SynchronousEventBeat::lockExecutorAndBeat() const { return; } - executeSynchronouslyOnSameThread_CAN_DEADLOCK( - runtimeExecutor_, [this](jsi::Runtime &runtime) { beat(runtime); }); + if (runtimeScheduler_) { + runtimeScheduler_->executeNowOnTheSameThread( + [this](jsi::Runtime &runtime) { beat(runtime); }); + } else { + executeSynchronouslyOnSameThread_CAN_DEADLOCK( + runtimeExecutor_, [this](jsi::Runtime &runtime) { beat(runtime); }); + } } } // namespace react diff --git a/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.h b/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.h index 109a6ddf0b625d..a3e2d6489d18db 100644 --- a/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.h +++ b/ReactCommon/react/renderer/scheduler/SynchronousEventBeat.h @@ -9,6 +9,7 @@ #include #include +#include #include namespace facebook { @@ -23,7 +24,8 @@ class SynchronousEventBeat final : public EventBeat, public: SynchronousEventBeat( RunLoopObserver::Unique uiRunLoopObserver, - RuntimeExecutor runtimeExecutor); + RuntimeExecutor runtimeExecutor, + std::shared_ptr const &runtimeScheduler); void induce() const override; @@ -38,6 +40,7 @@ class SynchronousEventBeat final : public EventBeat, RunLoopObserver::Unique uiRunLoopObserver_; RuntimeExecutor runtimeExecutor_; + std::shared_ptr runtimeScheduler_; }; } // namespace react diff --git a/ReactCommon/react/renderer/telemetry/BUCK b/ReactCommon/react/renderer/telemetry/BUCK index f19ae71f0c3c34..3ec301b4839def 100644 --- a/ReactCommon/react/renderer/telemetry/BUCK +++ b/ReactCommon/react/renderer/telemetry/BUCK @@ -79,5 +79,6 @@ fb_xplat_cxx_test( ":telemetry", "//xplat/folly:molly", "//xplat/third-party/gmock:gtest", + react_native_xplat_target("react/test_utils:test_utils"), ], ) diff --git a/ReactCommon/react/renderer/telemetry/tests/TransactionTelemetryTest.cpp b/ReactCommon/react/renderer/telemetry/tests/TransactionTelemetryTest.cpp index f5e2ef488e1728..95c6dfcf1b0785 100644 --- a/ReactCommon/react/renderer/telemetry/tests/TransactionTelemetryTest.cpp +++ b/ReactCommon/react/renderer/telemetry/tests/TransactionTelemetryTest.cpp @@ -11,29 +11,11 @@ #include #include +#include #include using namespace facebook::react; -class MockClock { - public: - typedef std::chrono:: - time_point - time_point; - - static time_point now() noexcept { - return time_; - } - - template - static void advance_by(const TDuration duration) { - time_ += duration; - } - - private: - static time_point time_; -}; - MockClock::time_point MockClock::time_ = {}; /** diff --git a/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp b/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp index 22d506efdcfda7..d9f4e44d1dc8b4 100644 --- a/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp +++ b/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp @@ -44,14 +44,14 @@ SharedShadowNode UITemplateProcessor::runCommand( const int tagOffset = 420000; // TODO: change to integer codes and a switch statement if (opcode == "createNode") { - int tag = command[1].asInt(); + Tag tag = static_cast(command[1].asInt()); const auto &type = command[2].asString(); const auto parentTag = command[3].asInt(); const auto &props = command[4]; nodes[tag] = componentDescriptorRegistry.createNode( tag + tagOffset, type, surfaceId, props, nullptr); if (parentTag > -1) { // parentTag == -1 indicates root node - auto parentShadowNode = nodes[parentTag]; + auto parentShadowNode = nodes[static_cast(parentTag)]; auto const &componentDescriptor = componentDescriptorRegistry.at( parentShadowNode->getComponentHandle()); componentDescriptor.appendChild(parentShadowNode, nodes[tag]); @@ -61,13 +61,13 @@ SharedShadowNode UITemplateProcessor::runCommand( LOG(INFO) << "(stop) UITemplateProcessor inject serialized 'server rendered' view tree"; } - return nodes[command[1].asInt()]; + return nodes[static_cast(command[1].asInt())]; } else if (opcode == "loadNativeBool") { - int registerNumber = command[1].asInt(); + auto registerNumber = static_cast(command[1].asInt()); std::string param = command[4][0].asString(); registers[registerNumber] = reactNativeConfig->getBool(param); } else if (opcode == "conditional") { - int registerNumber = command[1].asInt(); + auto registerNumber = static_cast(command[1].asInt()); auto conditionDynamic = registers[registerNumber]; if (conditionDynamic.isNull()) { // TODO: provide original command or command line? diff --git a/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.cpp b/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.cpp index db9910fecb5a16..76bbc45c963404 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.cpp +++ b/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.cpp @@ -34,7 +34,8 @@ LineMeasurement::LineMeasurement( frame(frame), descender(descender), capHeight(capHeight), - ascender(ascender) {} + ascender(ascender), + xHeight(xHeight) {} LineMeasurement::LineMeasurement(folly::dynamic const &data) : text(data.getDefault("text", "").getString()), diff --git a/ReactCommon/react/renderer/uimanager/UIManager.cpp b/ReactCommon/react/renderer/uimanager/UIManager.cpp index 74634904d77e95..a1c9d3612b560e 100644 --- a/ReactCommon/react/renderer/uimanager/UIManager.cpp +++ b/ReactCommon/react/renderer/uimanager/UIManager.cpp @@ -18,25 +18,21 @@ namespace facebook::react { -static std::unique_ptr constructLeakChecker( - RuntimeExecutor const &runtimeExecutor, - GarbageCollectionTrigger const &garbageCollectionTrigger) { - if (garbageCollectionTrigger) { - return std::make_unique( - runtimeExecutor, garbageCollectionTrigger); - } else { - return {}; - } +static std::unique_ptr constructLeakCheckerIfNeeded( + RuntimeExecutor const &runtimeExecutor) { +#ifdef REACT_NATIVE_DEBUG + return std::make_unique(runtimeExecutor); +#else + return {}; +#endif } UIManager::UIManager( RuntimeExecutor const &runtimeExecutor, - BackgroundExecutor const &backgroundExecutor, - GarbageCollectionTrigger const &garbageCollectionTrigger) + BackgroundExecutor const &backgroundExecutor) : runtimeExecutor_(runtimeExecutor), backgroundExecutor_(backgroundExecutor), - leakChecker_( - constructLeakChecker(runtimeExecutor, garbageCollectionTrigger)) {} + leakChecker_(constructLeakCheckerIfNeeded(runtimeExecutor)) {} UIManager::~UIManager() { LOG(WARNING) << "UIManager::~UIManager() was called (address: " << this @@ -364,19 +360,10 @@ UIManagerDelegate *UIManager::getDelegate() { void UIManager::visitBinding( std::function callback, jsi::Runtime &runtime) const { - if (extractUIManagerBindingOnDemand_) { - auto uiManagerBinding = UIManagerBinding::getBinding(runtime); - if (uiManagerBinding) { - callback(*uiManagerBinding_); - } - return; - } - - if (!uiManagerBinding_) { - return; + auto uiManagerBinding = UIManagerBinding::getBinding(runtime); + if (uiManagerBinding) { + callback(*uiManagerBinding); } - - callback(*uiManagerBinding_); } ShadowTreeRegistry const &UIManager::getShadowTreeRegistry() const { diff --git a/ReactCommon/react/renderer/uimanager/UIManager.h b/ReactCommon/react/renderer/uimanager/UIManager.h index 0133b1cb710747..ebb8a419bd041c 100644 --- a/ReactCommon/react/renderer/uimanager/UIManager.h +++ b/ReactCommon/react/renderer/uimanager/UIManager.h @@ -33,8 +33,7 @@ class UIManager final : public ShadowTreeDelegate { public: UIManager( RuntimeExecutor const &runtimeExecutor, - BackgroundExecutor const &backgroundExecutor, - GarbageCollectionTrigger const &garbageCollectionTrigger); + BackgroundExecutor const &backgroundExecutor); ~UIManager(); @@ -187,7 +186,6 @@ class UIManager final : public ShadowTreeDelegate { SharedComponentDescriptorRegistry componentDescriptorRegistry_; UIManagerDelegate *delegate_; UIManagerAnimationDelegate *animationDelegate_{nullptr}; - UIManagerBinding *uiManagerBinding_; RuntimeExecutor const runtimeExecutor_{}; ShadowTreeRegistry shadowTreeRegistry_{}; BackgroundExecutor const backgroundExecutor_{}; @@ -195,8 +193,6 @@ class UIManager final : public ShadowTreeDelegate { mutable better::shared_mutex commitHookMutex_; mutable std::vector commitHooks_; - bool extractUIManagerBindingOnDemand_{}; - std::unique_ptr leakChecker_; }; diff --git a/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp b/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp index 744de426797861..b6fc4401586e2e 100644 --- a/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp +++ b/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp @@ -96,25 +96,10 @@ std::shared_ptr UIManagerBinding::getBinding( UIManagerBinding::~UIManagerBinding() { LOG(WARNING) << "UIManagerBinding::~UIManagerBinding() was called (address: " << this << ")."; - - // We must detach the `UIBinding` on deallocation to prevent accessing - // deallocated `UIManagerBinding`. - // Since `UIManagerBinding` retains `UIManager`, `UIManager` always overlive - // `UIManagerBinding`, therefore we don't need similar logic in `UIManager`'s - // destructor. - attach(nullptr); } void UIManagerBinding::attach(std::shared_ptr const &uiManager) { - if (uiManager_) { - uiManager_->uiManagerBinding_ = nullptr; - } - uiManager_ = uiManager; - - if (uiManager_) { - uiManager_->uiManagerBinding_ = this; - } } static jsi::Value callMethodOfModule( @@ -230,6 +215,7 @@ void UIManagerBinding::dispatchEvent( jsi::Runtime &runtime, EventTarget const *eventTarget, std::string const &type, + ReactEventPriority priority, ValueFactory const &payloadFactory) const { SystraceSection s("UIManagerBinding::dispatchEvent"); @@ -260,11 +246,13 @@ void UIManagerBinding::dispatchEvent( auto &eventHandlerWrapper = static_cast(*eventHandler_); + currentEventPriority_ = priority; eventHandlerWrapper.callback.call( runtime, {std::move(instanceHandle), jsi::String::createFromUtf8(runtime, type), std::move(payload)}); + currentEventPriority_ = ReactEventPriority::Default; } void UIManagerBinding::invalidate() const { @@ -789,6 +777,28 @@ jsi::Value UIManagerBinding::get( }); } + if (methodName == "unstable_getCurrentEventPriority") { + return jsi::Function::createFromHostFunction( + runtime, + name, + 0, + [this]( + jsi::Runtime &, + jsi::Value const &, + jsi::Value const *, + size_t) noexcept -> jsi::Value { + return jsi::Value(serialize(currentEventPriority_)); + }); + } + + if (methodName == "unstable_DefaultEventPriority") { + return jsi::Value(serialize(ReactEventPriority::Default)); + } + + if (methodName == "unstable_DiscreteEventPriority") { + return jsi::Value(serialize(ReactEventPriority::Discrete)); + } + return jsi::Value::undefined(); } diff --git a/ReactCommon/react/renderer/uimanager/UIManagerBinding.h b/ReactCommon/react/renderer/uimanager/UIManagerBinding.h index c20e6c0fb655dc..14032451d6df1e 100644 --- a/ReactCommon/react/renderer/uimanager/UIManagerBinding.h +++ b/ReactCommon/react/renderer/uimanager/UIManagerBinding.h @@ -82,6 +82,7 @@ class UIManagerBinding : public jsi::HostObject { jsi::Runtime &runtime, EventTarget const *eventTarget, std::string const &type, + ReactEventPriority priority, ValueFactory const &payloadFactory) const; /* @@ -101,6 +102,7 @@ class UIManagerBinding : public jsi::HostObject { private: std::shared_ptr uiManager_; std::unique_ptr eventHandler_; + mutable ReactEventPriority currentEventPriority_; }; } // namespace facebook::react diff --git a/ReactCommon/react/test_utils/BUCK b/ReactCommon/react/test_utils/BUCK new file mode 100644 index 00000000000000..52bae03fe6c520 --- /dev/null +++ b/ReactCommon/react/test_utils/BUCK @@ -0,0 +1,54 @@ +load( + "//tools/build_defs/oss:rn_defs.bzl", + "ANDROID", + "APPLE", + "CXX", + "get_apple_compiler_flags", + "get_apple_inspector_flags", + "get_preprocessor_flags_for_build_mode", + "react_native_xplat_target", + "rn_xplat_cxx_library", + "subdir_glob", +) + +APPLE_COMPILER_FLAGS = get_apple_compiler_flags() + +rn_xplat_cxx_library( + name = "test_utils", + srcs = [], + headers = glob( + ["**/*.h"], + exclude = glob(["tests/**/*.h"]), + ), + header_namespace = "", + exported_headers = subdir_glob( + [ + ("", "*.h"), + ], + prefix = "react/test_utils", + ), + compiler_flags = [ + "-fexceptions", + "-frtti", + "-std=c++17", + "-Wall", + ], + fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, + fbobjc_frameworks = ["Foundation"], + fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), + force_static = True, + labels = ["supermodule:xplat/default/public.react_native.infra"], + macosx_tests_override = [], + platforms = (ANDROID, APPLE, CXX), + preprocessor_flags = [ + "-DLOG_TAG=\"ReactNative\"", + "-DWITH_FBSYSTRACE=1", + ], + tests = [], + visibility = ["PUBLIC"], + deps = [ + "//xplat/jsi:jsi", + react_native_xplat_target("better:better"), + react_native_xplat_target("react/debug:debug"), + ], +) diff --git a/ReactCommon/react/renderer/mounting/tests/Entropy.h b/ReactCommon/react/test_utils/Entropy.h similarity index 100% rename from ReactCommon/react/renderer/mounting/tests/Entropy.h rename to ReactCommon/react/test_utils/Entropy.h diff --git a/ReactCommon/react/test_utils/MockClock.h b/ReactCommon/react/test_utils/MockClock.h new file mode 100644 index 00000000000000..a5155207b2078a --- /dev/null +++ b/ReactCommon/react/test_utils/MockClock.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +class MockClock { + public: + typedef std::chrono:: + time_point + time_point; + + static time_point now() noexcept { + return time_; + } + + template + static void advance_by(const TDuration duration) { + time_ += duration; + } + + private: + static time_point time_; +}; diff --git a/ReactCommon/react/renderer/mounting/tests/shadowTreeGeneration.h b/ReactCommon/react/test_utils/shadowTreeGeneration.h similarity index 100% rename from ReactCommon/react/renderer/mounting/tests/shadowTreeGeneration.h rename to ReactCommon/react/test_utils/shadowTreeGeneration.h diff --git a/ReactCommon/reactperflogger/React-perflogger.podspec b/ReactCommon/reactperflogger/React-perflogger.podspec index d66d7120365557..75b88cdd94d79b 100644 --- a/ReactCommon/reactperflogger/React-perflogger.podspec +++ b/ReactCommon/reactperflogger/React-perflogger.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' Pod::Spec.new do |s| diff --git a/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec b/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec index 9cd26396a818c6..fc4ffd161ef9bb 100644 --- a/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec +++ b/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' boost_compiler_flags = '-Wno-documentation' Pod::Spec.new do |s| diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index 33f70e8292258e..2c68674a742933 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -4194,9 +4194,7 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( if (node->getConfig()->printTree) { YGNodePrint( node, - (YGPrintOptions)( - YGPrintOptionsLayout | YGPrintOptionsChildren | - YGPrintOptionsStyle)); + (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); } #endif } @@ -4256,9 +4254,7 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( if (nodeWithoutLegacyFlag->getConfig()->printTree) { YGNodePrint( nodeWithoutLegacyFlag, - (YGPrintOptions)( - YGPrintOptionsLayout | YGPrintOptionsChildren | - YGPrintOptionsStyle)); + (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); } #endif } diff --git a/build.gradle.kts b/build.gradle.kts index 42289d9ec80349..cb1e3bf9d482aa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,9 +40,7 @@ allprojects { mavenCentral() jcenter { content { - includeModule("org.jetbrains.trove4j", "trove4j") includeModule("com.facebook.yoga", "proguard-annotations") - includeModule("com.facebook.fbjni", "fbjni-java-only") includeModule("com.facebook.fresco", "stetho") } } diff --git a/gradlew.bat b/gradlew.bat index ac1b06f93825db..107acd32c4e687 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,89 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/index.js b/index.js index 6062f45ea064a1..db77f7dc519aa2 100644 --- a/index.js +++ b/index.js @@ -244,7 +244,7 @@ module.exports = { return require('./Libraries/Components/StatusBar/StatusBar'); }, get Switch(): Switch { - return require('./Libraries/Components/Switch/Switch'); + return require('./Libraries/Components/Switch/Switch').default; }, get Text(): Text { return require('./Libraries/Text/Text'); @@ -479,7 +479,7 @@ module.exports = { ) => HostComponent { return require('./Libraries/ReactNative/requireNativeComponent'); }, - get unstable_RootTagContext(): RootTagContext { + get RootTagContext(): RootTagContext { return require('./Libraries/ReactNative/RootTag').RootTagContext; }, get unstable_enableLogBox(): () => void { diff --git a/jest/setup.js b/jest/setup.js index c759924d23c38b..2ffa8ecddfb9c4 100644 --- a/jest/setup.js +++ b/jest/setup.js @@ -70,7 +70,7 @@ jest } }), hasViewManagerConfig: jest.fn(name => { - return true; + return name === 'AndroidDrawerLayout'; }), measure: jest.fn(), manageChildren: jest.fn(), diff --git a/package.json b/package.json index 98106cbd4ebe04..b88efe7dd751f7 100644 --- a/package.json +++ b/package.json @@ -100,18 +100,18 @@ "anser": "^1.4.9", "base64-js": "^1.1.2", "event-target-shim": "^5.0.1", - "hermes-engine": "~0.7.0", + "hermes-engine": "~0.8.0", "invariant": "^2.2.4", - "jsc-android": "^245459.0.0", - "metro-babel-register": "0.65.2", - "metro-react-native-babel-transformer": "0.65.2", - "metro-runtime": "0.65.2", - "metro-source-map": "0.65.2", + "jsc-android": "^250230.2.1", + "metro-babel-register": "0.66.0", + "metro-react-native-babel-transformer": "0.66.0", + "metro-runtime": "0.66.0", + "metro-source-map": "0.66.0", "nullthrows": "^1.1.1", "pretty-format": "^26.5.2", "promise": "^8.0.3", "prop-types": "^15.7.2", - "react-devtools-core": "^4.6.0", + "react-devtools-core": "^4.13.0", "react-refresh": "^0.4.0", "regenerator-runtime": "^0.13.2", "scheduler": "^0.20.1", @@ -121,7 +121,7 @@ "ws": "^6.1.4" }, "devDependencies": { - "flow-bin": "^0.148.0", + "flow-bin": "^0.152.0", "react": "17.0.2" }, "detox": { diff --git a/packages/babel-plugin-codegen/__tests__/__snapshots__/index-test.js.snap b/packages/babel-plugin-codegen/__tests__/__snapshots__/index-test.js.snap index 7018db249d9a9d..54d4e46fd900cd 100644 --- a/packages/babel-plugin-codegen/__tests__/__snapshots__/index-test.js.snap +++ b/packages/babel-plugin-codegen/__tests__/__snapshots__/index-test.js.snap @@ -133,32 +133,32 @@ export default 'Not a view config';" exports[`Babel plugin inline view configs fails on inline config for CommandsExportedWithDifferentNameNativeComponent.js 1`] = ` "/CommandsExportedWithDifferentNameNativeComponent.js: Native commands must be exported with the name 'Commands' 17 | } - 18 | + 18 | > 19 | export const Foo = codegenNativeCommands(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 20 | + 20 | 21 | export default (codegenNativeComponent('Module'): NativeType); - 22 | " + 22 |" `; exports[`Babel plugin inline view configs fails on inline config for CommandsExportedWithShorthandNativeComponent.js 1`] = ` "/CommandsExportedWithShorthandNativeComponent.js: 'Commands' is a reserved export and may only be used to export the result of codegenNativeCommands. 19 | const Commands = 4; - 20 | + 20 | > 21 | export {Commands}; | ^^^^^^^^^^^^^^^^^^ - 22 | + 22 | 23 | export default (codegenNativeComponent('Module'): NativeType); - 24 | " + 24 |" `; exports[`Babel plugin inline view configs fails on inline config for OtherCommandsExportNativeComponent.js 1`] = ` "/OtherCommandsExportNativeComponent.js: 'Commands' is a reserved export and may only be used to export the result of codegenNativeCommands. 17 | } - 18 | + 18 | > 19 | export const Commands = 4; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - 20 | + 20 | 21 | export default (codegenNativeComponent('Module'): NativeType); - 22 | " + 22 |" `; diff --git a/packages/babel-plugin-codegen/__tests__/index-test.js b/packages/babel-plugin-codegen/__tests__/index-test.js index a62d5eb0dfa6dd..06b9ad76dfe469 100644 --- a/packages/babel-plugin-codegen/__tests__/index-test.js +++ b/packages/babel-plugin-codegen/__tests__/index-test.js @@ -17,6 +17,7 @@ const failures = require('../__test_fixtures__/failures.js'); const transform = (fixture, filename) => babelTransform(fixture, { babelrc: false, + browserslistConfigFile: false, cwd: '/', filename: filename, highlightCode: false, diff --git a/packages/babel-plugin-codegen/index.js b/packages/babel-plugin-codegen/index.js index 3b3ee570946806..6381b31a2b4e2f 100644 --- a/packages/babel-plugin-codegen/index.js +++ b/packages/babel-plugin-codegen/index.js @@ -124,7 +124,10 @@ module.exports = function({parse, types: t}) { if (this.defaultExport) { const viewConfig = generateViewConfig(this.filename, this.code); this.defaultExport.replaceWithMultiple( - parse(viewConfig).program.body, + parse(viewConfig, { + babelrc: false, + browserslistConfigFile: false, + }).program.body, ); if (this.commandsExport != null) { this.commandsExport.remove(); diff --git a/packages/babel-plugin-codegen/package.json b/packages/babel-plugin-codegen/package.json index e5176600ae0476..858148ff6ae1fb 100644 --- a/packages/babel-plugin-codegen/package.json +++ b/packages/babel-plugin-codegen/package.json @@ -11,7 +11,7 @@ "react-native-codegen": "*" }, "devDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.14.0" }, "license": "MIT" } diff --git a/packages/eslint-config-react-native-community/index.js b/packages/eslint-config-react-native-community/index.js index 716bdb56e8a2ae..320ef4daf2b16c 100644 --- a/packages/eslint-config-react-native-community/index.js +++ b/packages/eslint-config-react-native-community/index.js @@ -72,6 +72,7 @@ module.exports = { }, rules: { 'react-native/no-inline-styles': 0, + quotes: [1, 'single', {avoidEscape: true, allowTemplateLiterals: true}], }, }, ], diff --git a/packages/eslint-plugin-codegen/package.json b/packages/eslint-plugin-codegen/package.json index bb0c49d193183f..f82575f74cb036 100644 --- a/packages/eslint-plugin-codegen/package.json +++ b/packages/eslint-plugin-codegen/package.json @@ -9,7 +9,7 @@ "directory": "packages/eslint-plugin-codegen" }, "dependencies": { - "@babel/core": "^7.0.0", + "@babel/core": "^7.14.0", "@babel/plugin-transform-flow-strip-types": "^7.0.0", "flow-parser": "^0.121.0", "make-dir": "^2.1.0", diff --git a/packages/react-native-codegen/BUCK b/packages/react-native-codegen/BUCK index 0f9a462f33ac2c..aa142865463e7c 100644 --- a/packages/react-native-codegen/BUCK +++ b/packages/react-native-codegen/BUCK @@ -29,6 +29,7 @@ rn_codegen_components( rn_codegen_modules( name = "FBReactNativeTestSpec", android_package_name = "com.facebook.fbreact.specs", + ios_assume_nonnull = False, schema_target = ":codegen_tests_schema", ) diff --git a/packages/react-native-codegen/DEFS.bzl b/packages/react-native-codegen/DEFS.bzl index 3652e494556cba..7377ca42e0ba82 100644 --- a/packages/react-native-codegen/DEFS.bzl +++ b/packages/react-native-codegen/DEFS.bzl @@ -105,6 +105,7 @@ def rn_codegen_cli(): def rn_codegen_modules( name, android_package_name, + ios_assume_nonnull, library_labels = [], schema_target = ""): generate_fixtures_rule_name = "{}-codegen-modules".format(name) @@ -118,11 +119,12 @@ def rn_codegen_modules( fb_native.genrule( name = generate_fixtures_rule_name, srcs = native.glob(["src/generators/**/*.js"]), - cmd = "$(exe {generator_script}) $(location {schema_target}) {library_name} $OUT {android_package_name}".format( + cmd = "$(exe {generator_script}) $(location {schema_target}) {library_name} $OUT {android_package_name} {ios_assume_nonnull}".format( generator_script = react_native_root_target("packages/react-native-codegen:generate_all_from_schema"), schema_target = schema_target, library_name = name, android_package_name = android_package_name, + ios_assume_nonnull = ios_assume_nonnull, ), out = "codegenfiles-{}".format(name), labels = ["codegen_rule"], diff --git a/packages/react-native-codegen/android/gradlew.bat b/packages/react-native-codegen/android/gradlew.bat index ac1b06f93825db..107acd32c4e687 100644 --- a/packages/react-native-codegen/android/gradlew.bat +++ b/packages/react-native-codegen/android/gradlew.bat @@ -1,89 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/react-native-codegen/e2e/__tests__/modules/GenerateModuleObjCpp-test.js b/packages/react-native-codegen/e2e/__tests__/modules/GenerateModuleObjCpp-test.js index 039c05323bdd08..62f923d9581d23 100644 --- a/packages/react-native-codegen/e2e/__tests__/modules/GenerateModuleObjCpp-test.js +++ b/packages/react-native-codegen/e2e/__tests__/modules/GenerateModuleObjCpp-test.js @@ -38,13 +38,19 @@ function getModules(): SchemaType { describe('GenerateModuleObjCpp', () => { it('can generate a header file NativeModule specs', () => { const libName = 'RNCodegenModuleFixtures'; - const output = generator.generate(libName, getModules()); + const output = generator.generate(libName, getModules(), undefined, false); + expect(output.get(libName + '.h')).toMatchSnapshot(); + }); + + it('can generate a header file NativeModule specs with assume nonnull enabled', () => { + const libName = 'RNCodegenModuleFixtures'; + const output = generator.generate(libName, getModules(), undefined, true); expect(output.get(libName + '.h')).toMatchSnapshot(); }); it('can generate an implementation file NativeModule specs', () => { const libName = 'RNCodegenModuleFixtures'; - const output = generator.generate(libName, getModules()); + const output = generator.generate(libName, getModules(), undefined, false); expect(output.get(libName + '-generated.mm')).toMatchSnapshot(); }); }); diff --git a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap index 435e5d6471ec2a..72435804ab9543 100644 --- a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap @@ -1190,6 +1190,1199 @@ inline JS::NativeSampleTurboModuleOptional::Constants::Builder::Builder(Constant " `; +exports[`GenerateModuleObjCpp can generate a header file NativeModule specs with assume nonnull enabled 1`] = ` +"/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleObjCpp + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. + */ + +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + + +NS_ASSUME_NONNULL_BEGIN + +@protocol NativeArrayTurboModuleSpec + +- (NSArray *)getArray:(NSArray *)a; +- (NSArray *)getReadOnlyArray:(NSArray *)a; +- (NSArray *)getArrayWithAlias:(NSArray *)a + b:(NSArray *)b; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeArrayTurboModule' + */ + class JSI_EXPORT NativeArrayTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeArrayTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + +@protocol NativeBooleanTurboModuleSpec + +- (NSNumber *)getBoolean:(BOOL)arg; +- (NSNumber *)getBooleanWithAlias:(BOOL)arg; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeBooleanTurboModule' + */ + class JSI_EXPORT NativeBooleanTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeBooleanTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + +@protocol NativeCallbackTurboModuleSpec + +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithCallbackWithAlias:(RCTResponseSenderBlock)c; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeCallbackTurboModule' + */ + class JSI_EXPORT NativeCallbackTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeCallbackTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + +@protocol NativeNullableTurboModuleSpec + +- (NSNumber * _Nullable)getBool:(NSNumber *)a; +- (NSNumber * _Nullable)getNumber:(NSNumber *)a; +- (NSString * _Nullable)getString:(NSNumber *)a; +- (NSArray> * _Nullable)getArray:(NSArray * _Nullable)a; +- (NSDictionary * _Nullable)getObject:(NSDictionary * _Nullable)a; +- (void)getValueWithPromise:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeNullableTurboModule' + */ + class JSI_EXPORT NativeNullableTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeNullableTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + +@protocol NativeNumberTurboModuleSpec + +- (NSNumber *)getNumber:(double)arg; +- (NSNumber *)getNumberWithAlias:(double)arg; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeNumberTurboModule' + */ + class JSI_EXPORT NativeNumberTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeNumberTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +namespace JS { + namespace NativeObjectTurboModule { + struct SpecDifficultObjectAE { + bool D() const; + double E() const; + NSString *F() const; + + SpecDifficultObjectAE(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeObjectTurboModule_SpecDifficultObjectAE) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_SpecDifficultObjectAE:(id)json; +@end +namespace JS { + namespace NativeObjectTurboModule { + struct SpecDifficultObjectA { + bool D() const; + JS::NativeObjectTurboModule::SpecDifficultObjectAE E() const; + NSString *F() const; + + SpecDifficultObjectA(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeObjectTurboModule_SpecDifficultObjectA) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_SpecDifficultObjectA:(id)json; +@end +namespace JS { + namespace NativeObjectTurboModule { + struct ConstantsEEE { + + struct Builder { + struct Input { + RCTRequired D; + RCTRequired E; + RCTRequired F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsEEE */ + Builder(ConstantsEEE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsEEE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsEEE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +namespace JS { + namespace NativeObjectTurboModule { + struct ConstantsEE { + + struct Builder { + struct Input { + RCTRequired D; + RCTRequired E; + RCTRequired F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsEE */ + Builder(ConstantsEE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsEE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsEE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +namespace JS { + namespace NativeObjectTurboModule { + struct ConstantsE { + + struct Builder { + struct Input { + RCTRequired D; + RCTRequired E; + RCTRequired F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsE */ + Builder(ConstantsE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +namespace JS { + namespace NativeObjectTurboModule { + struct Constants { + + struct Builder { + struct Input { + RCTRequired D; + RCTRequired E; + RCTRequired F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeObjectTurboModuleSpec + +- (NSDictionary *)getGenericObject:(NSDictionary *)arg; +- (NSDictionary *)getGenericObjectReadOnly:(NSDictionary *)arg; +- (NSDictionary *)getGenericObjectWithAlias:(NSDictionary *)arg; +- (NSDictionary *)difficultObject:(JS::NativeObjectTurboModule::SpecDifficultObjectA &)A; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeObjectTurboModule' + */ + class JSI_EXPORT NativeObjectTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeObjectTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +namespace JS { + namespace NativeOptionalObjectTurboModule { + struct ConstantsEEE { + + struct Builder { + struct Input { + folly::Optional D; + folly::Optional E; + NSString *F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsEEE */ + Builder(ConstantsEEE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsEEE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsEEE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +namespace JS { + namespace NativeOptionalObjectTurboModule { + struct ConstantsEE { + + struct Builder { + struct Input { + folly::Optional D; + folly::Optional E; + NSString *F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsEE */ + Builder(ConstantsEE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsEE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsEE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +namespace JS { + namespace NativeOptionalObjectTurboModule { + struct ConstantsE { + + struct Builder { + struct Input { + folly::Optional D; + folly::Optional E; + NSString *F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsE */ + Builder(ConstantsE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +namespace JS { + namespace NativeOptionalObjectTurboModule { + struct Constants { + + struct Builder { + struct Input { + folly::Optional D; + id _Nullable A; + folly::Optional E; + NSString *F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeOptionalObjectTurboModuleSpec + +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeOptionalObjectTurboModule' + */ + class JSI_EXPORT NativeOptionalObjectTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeOptionalObjectTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + +@protocol NativePromiseTurboModuleSpec + +- (void)getValueWithPromise:(BOOL)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)getValueWithPromiseWithAlias:(NSString *)arg + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativePromiseTurboModule' + */ + class JSI_EXPORT NativePromiseTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativePromiseTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +namespace JS { + namespace NativeSampleTurboModule { + struct SpecGetObjectShapeArg { + double prop() const; + + SpecGetObjectShapeArg(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetObjectShapeArg:(id)json; +@end +namespace JS { + namespace NativeSampleTurboModule { + struct Animal { + NSString *name() const; + + Animal(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_Animal:(id)json; +@end +namespace JS { + namespace NativeSampleTurboModule { + struct Constants { + + struct Builder { + struct Input { + RCTRequired const1; + RCTRequired const2; + RCTRequired const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleSpec + +- (void)voidFunc; +- (NSNumber *)getBool:(BOOL)arg; +- (NSNumber *)getNumber:(double)arg; +- (NSString *)getString:(NSString *)arg; +- (NSArray> *)getArray:(NSArray *)arg; +- (NSDictionary *)getObject:(NSDictionary *)arg; +- (NSDictionary *)getObjectShape:(JS::NativeSampleTurboModule::SpecGetObjectShapeArg &)arg; +- (NSDictionary *)getAlias:(JS::NativeSampleTurboModule::Animal &)arg; +- (NSNumber *)getRootTag:(double)arg; +- (NSDictionary *)getValue:(double)x +getValuegetValuegetValuegetValuegetValuey:(NSString *)getValuegetValuegetValuegetValuegetValuey + z:(NSDictionary *)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(BOOL)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeSampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +namespace JS { + namespace NativeSampleTurboModuleArrays { + struct ConstantsIdElement { + + struct Builder { + struct Input { + RCTRequired prop; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsIdElement */ + Builder(ConstantsIdElement i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsIdElement fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsIdElement(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +namespace JS { + namespace NativeSampleTurboModuleArrays { + struct Constants { + + struct Builder { + struct Input { + RCTRequired> const1; + RCTRequired> const2; + RCTRequired> const3; + folly::Optional>> id_; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleArraysSpec + +- (void)voidFunc; +- (NSArray *)getBool:(NSArray *)id; +- (NSArray *)getNumber:(NSArray *)arg; +- (NSArray *)getString:(NSArray *)arg; +- (NSArray> *> *)getArray:(NSArray *)arg; +- (NSArray *)getObject:(NSArray *)arg; +- (NSArray *)getObjectShape:(NSArray *)arg; +- (NSArray *)getAlias:(NSArray *)arg; +- (NSArray *)getRootTag:(NSArray *)arg; +- (NSArray *)getValue:(NSArray *)x + y:(NSArray *)y + z:(NSArray *)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(NSArray *)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeSampleTurboModuleArrays' + */ + class JSI_EXPORT NativeSampleTurboModuleArraysSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleArraysSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +namespace JS { + namespace NativeSampleTurboModuleNullable { + struct SpecGetObjectShapeArg { + folly::Optional prop() const; + + SpecGetObjectShapeArg(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleNullable_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullable_SpecGetObjectShapeArg:(id)json; +@end +namespace JS { + namespace NativeSampleTurboModuleNullable { + struct Animal { + NSString *name() const; + + Animal(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleNullable_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullable_Animal:(id)json; +@end +namespace JS { + namespace NativeSampleTurboModuleNullable { + struct Constants { + + struct Builder { + struct Input { + RCTRequired> const1; + RCTRequired> const2; + RCTRequired const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleNullableSpec + +- (void)voidFunc; +- (NSNumber * _Nullable)getBool:(NSNumber *)arg; +- (NSNumber * _Nullable)getNumber:(NSNumber *)arg; +- (NSString * _Nullable)getString:(NSString * _Nullable)arg; +- (NSArray> * _Nullable)getArray:(NSArray * _Nullable)arg; +- (NSDictionary * _Nullable)getObject:(NSDictionary * _Nullable)arg; +- (NSDictionary * _Nullable)getObjectShape:(JS::NativeSampleTurboModuleNullable::SpecGetObjectShapeArg &)arg; +- (NSDictionary * _Nullable)getAlias:(JS::NativeSampleTurboModuleNullable::Animal &)arg; +- (NSNumber * _Nullable)getRootTag:(NSNumber *)arg; +- (NSDictionary * _Nullable)getValue:(NSNumber *)x + y:(NSString * _Nullable)y + z:(NSDictionary * _Nullable)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(NSNumber *)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeSampleTurboModuleNullable' + */ + class JSI_EXPORT NativeSampleTurboModuleNullableSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleNullableSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +namespace JS { + namespace NativeSampleTurboModuleNullableAndOptional { + struct SpecGetObjectShapeArg { + folly::Optional prop() const; + + SpecGetObjectShapeArg(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleNullableAndOptional_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullableAndOptional_SpecGetObjectShapeArg:(id)json; +@end +namespace JS { + namespace NativeSampleTurboModuleNullableAndOptional { + struct Animal { + NSString *name() const; + + Animal(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleNullableAndOptional_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullableAndOptional_Animal:(id)json; +@end +namespace JS { + namespace NativeSampleTurboModuleNullableAndOptional { + struct Constants { + + struct Builder { + struct Input { + folly::Optional const1; + folly::Optional const2; + NSString *const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleNullableAndOptionalSpec + +- (void)voidFunc; +- (NSNumber * _Nullable)getBool:(NSNumber *)arg; +- (NSNumber * _Nullable)getNumber:(NSNumber *)arg; +- (NSString * _Nullable)getString:(NSString * _Nullable)arg; +- (NSArray> * _Nullable)getArray:(NSArray * _Nullable)arg; +- (NSDictionary * _Nullable)getObject:(NSDictionary * _Nullable)arg; +- (NSDictionary *)getObjectShape:(JS::NativeSampleTurboModuleNullableAndOptional::SpecGetObjectShapeArg &)arg; +- (NSDictionary * _Nullable)getAlias:(JS::NativeSampleTurboModuleNullableAndOptional::Animal &)arg; +- (NSNumber * _Nullable)getRootTag:(NSNumber *)arg; +- (NSDictionary * _Nullable)getValue:(NSNumber *)x + y:(NSString * _Nullable)y + z:(NSDictionary * _Nullable)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(NSNumber *)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeSampleTurboModuleNullableAndOptional' + */ + class JSI_EXPORT NativeSampleTurboModuleNullableAndOptionalSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleNullableAndOptionalSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +namespace JS { + namespace NativeSampleTurboModuleOptional { + struct SpecGetObjectShapeArg { + folly::Optional prop() const; + + SpecGetObjectShapeArg(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleOptional_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleOptional_SpecGetObjectShapeArg:(id)json; +@end +namespace JS { + namespace NativeSampleTurboModuleOptional { + struct Animal { + NSString *name() const; + + Animal(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleOptional_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleOptional_Animal:(id)json; +@end +namespace JS { + namespace NativeSampleTurboModuleOptional { + struct Constants { + + struct Builder { + struct Input { + folly::Optional const1; + folly::Optional const2; + NSString *const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleOptionalSpec + +- (void)voidFunc; +- (NSNumber *)getBool:(NSNumber *)arg; +- (NSNumber *)getNumber:(NSNumber *)arg; +- (NSString *)getString:(NSString *)arg; +- (NSArray> *)getArray:(NSArray *)arg; +- (NSDictionary *)getObject:(NSDictionary *)arg; +- (NSDictionary *)getObjectShape:(JS::NativeSampleTurboModuleOptional::SpecGetObjectShapeArg &)arg; +- (NSDictionary *)getAlias:(JS::NativeSampleTurboModuleOptional::Animal &)arg; +- (NSNumber *)getRootTag:(NSNumber *)arg; +- (NSDictionary *)getValue:(NSNumber *)x + y:(NSString *)y + z:(NSDictionary *)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(NSNumber *)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeSampleTurboModuleOptional' + */ + class JSI_EXPORT NativeSampleTurboModuleOptionalSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleOptionalSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + +@protocol NativeStringTurboModuleSpec + +- (NSString *)getString:(NSString *)arg; +- (NSString *)getStringWithAlias:(NSString *)arg; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NativeStringTurboModule' + */ + class JSI_EXPORT NativeStringTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeStringTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + + + +inline bool JS::NativeObjectTurboModule::SpecDifficultObjectAE::D() const +{ + id const p = _v[@\\"D\\"]; + return RCTBridgingToBool(p); +} +inline double JS::NativeObjectTurboModule::SpecDifficultObjectAE::E() const +{ + id const p = _v[@\\"E\\"]; + return RCTBridgingToDouble(p); +} +inline NSString *JS::NativeObjectTurboModule::SpecDifficultObjectAE::F() const +{ + id const p = _v[@\\"F\\"]; + return RCTBridgingToString(p); +} +inline bool JS::NativeObjectTurboModule::SpecDifficultObjectA::D() const +{ + id const p = _v[@\\"D\\"]; + return RCTBridgingToBool(p); +} +inline JS::NativeObjectTurboModule::SpecDifficultObjectAE JS::NativeObjectTurboModule::SpecDifficultObjectA::E() const +{ + id const p = _v[@\\"E\\"]; + return JS::NativeObjectTurboModule::SpecDifficultObjectAE(p); +} +inline NSString *JS::NativeObjectTurboModule::SpecDifficultObjectA::F() const +{ + id const p = _v[@\\"F\\"]; + return RCTBridgingToString(p); +} +inline JS::NativeObjectTurboModule::ConstantsEEE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D.get(); + d[@\\"D\\"] = @(D); + auto E = i.E.get(); + d[@\\"E\\"] = @(E); + auto F = i.F.get(); + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeObjectTurboModule::ConstantsEEE::Builder::Builder(ConstantsEEE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeObjectTurboModule::ConstantsEE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D.get(); + d[@\\"D\\"] = @(D); + auto E = i.E.get(); + d[@\\"E\\"] = E.buildUnsafeRawValue(); + auto F = i.F.get(); + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeObjectTurboModule::ConstantsEE::Builder::Builder(ConstantsEE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeObjectTurboModule::ConstantsE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D.get(); + d[@\\"D\\"] = @(D); + auto E = i.E.get(); + d[@\\"E\\"] = E.buildUnsafeRawValue(); + auto F = i.F.get(); + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeObjectTurboModule::ConstantsE::Builder::Builder(ConstantsE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeObjectTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D.get(); + d[@\\"D\\"] = @(D); + auto E = i.E.get(); + d[@\\"E\\"] = E.buildUnsafeRawValue(); + auto F = i.F.get(); + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeObjectTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsEEE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D; + d[@\\"D\\"] = D.hasValue() ? @((BOOL)D.value()) : nil; + auto E = i.E; + d[@\\"E\\"] = E.hasValue() ? @((double)E.value()) : nil; + auto F = i.F; + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsEEE::Builder::Builder(ConstantsEEE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsEE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D; + d[@\\"D\\"] = D.hasValue() ? @((BOOL)D.value()) : nil; + auto E = i.E; + d[@\\"E\\"] = E.hasValue() ? E.value().buildUnsafeRawValue() : nil; + auto F = i.F; + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsEE::Builder::Builder(ConstantsEE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D; + d[@\\"D\\"] = D.hasValue() ? @((BOOL)D.value()) : nil; + auto E = i.E; + d[@\\"E\\"] = E.hasValue() ? E.value().buildUnsafeRawValue() : nil; + auto F = i.F; + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsE::Builder::Builder(ConstantsE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeOptionalObjectTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D; + d[@\\"D\\"] = D.hasValue() ? @((BOOL)D.value()) : nil; + auto A = i.A; + d[@\\"A\\"] = A; + auto E = i.E; + d[@\\"E\\"] = E.hasValue() ? E.value().buildUnsafeRawValue() : nil; + auto F = i.F; + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeOptionalObjectTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline double JS::NativeSampleTurboModule::SpecGetObjectShapeArg::prop() const +{ + id const p = _v[@\\"prop\\"]; + return RCTBridgingToDouble(p); +} +inline NSString *JS::NativeSampleTurboModule::Animal::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToString(p); +} +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1.get(); + d[@\\"const1\\"] = @(const1); + auto const2 = i.const2.get(); + d[@\\"const2\\"] = @(const2); + auto const3 = i.const3.get(); + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeSampleTurboModuleArrays::ConstantsIdElement::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto prop = i.prop.get(); + d[@\\"prop\\"] = @(prop); + return d; +}) {} +inline JS::NativeSampleTurboModuleArrays::ConstantsIdElement::Builder::Builder(ConstantsIdElement i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline JS::NativeSampleTurboModuleArrays::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1.get(); + d[@\\"const1\\"] = RCTConvertVecToArray(const1, ^id(bool el_) { return @(el_); }); + auto const2 = i.const2.get(); + d[@\\"const2\\"] = RCTConvertVecToArray(const2, ^id(double el_) { return @(el_); }); + auto const3 = i.const3.get(); + d[@\\"const3\\"] = RCTConvertVecToArray(const3, ^id(NSString * el_) { return el_; }); + auto id_ = i.id_; + d[@\\"id\\"] = RCTConvertOptionalVecToArray(id_, ^id(folly::Optional el_) { return el_.hasValue() ? el_.value().buildUnsafeRawValue() : nil; }); + return d; +}) {} +inline JS::NativeSampleTurboModuleArrays::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline folly::Optional JS::NativeSampleTurboModuleNullable::SpecGetObjectShapeArg::prop() const +{ + id const p = _v[@\\"prop\\"]; + return RCTBridgingToOptionalDouble(p); +} +inline NSString *JS::NativeSampleTurboModuleNullable::Animal::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToOptionalString(p); +} +inline JS::NativeSampleTurboModuleNullable::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1.get(); + d[@\\"const1\\"] = const1.hasValue() ? @((BOOL)const1.value()) : nil; + auto const2 = i.const2.get(); + d[@\\"const2\\"] = const2.hasValue() ? @((double)const2.value()) : nil; + auto const3 = i.const3.get(); + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModuleNullable::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline folly::Optional JS::NativeSampleTurboModuleNullableAndOptional::SpecGetObjectShapeArg::prop() const +{ + id const p = _v[@\\"prop\\"]; + return RCTBridgingToOptionalDouble(p); +} +inline NSString *JS::NativeSampleTurboModuleNullableAndOptional::Animal::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToOptionalString(p); +} +inline JS::NativeSampleTurboModuleNullableAndOptional::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1; + d[@\\"const1\\"] = const1.hasValue() ? @((BOOL)const1.value()) : nil; + auto const2 = i.const2; + d[@\\"const2\\"] = const2.hasValue() ? @((double)const2.value()) : nil; + auto const3 = i.const3; + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModuleNullableAndOptional::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} +inline folly::Optional JS::NativeSampleTurboModuleOptional::SpecGetObjectShapeArg::prop() const +{ + id const p = _v[@\\"prop\\"]; + return RCTBridgingToOptionalDouble(p); +} +inline NSString *JS::NativeSampleTurboModuleOptional::Animal::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToOptionalString(p); +} +inline JS::NativeSampleTurboModuleOptional::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1; + d[@\\"const1\\"] = const1.hasValue() ? @((BOOL)const1.value()) : nil; + auto const2 = i.const2; + d[@\\"const2\\"] = const2.hasValue() ? @((double)const2.value()) : nil; + auto const3 = i.const3; + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModuleOptional::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +NS_ASSUME_NONNULL_END +" +`; + exports[`GenerateModuleObjCpp can generate an implementation file NativeModule specs 1`] = ` "/** * Copyright (c) Facebook, Inc. and its affiliates. diff --git a/packages/react-native-codegen/package.json b/packages/react-native-codegen/package.json index 0449b0c0793a55..2dfb1611ea2ea9 100644 --- a/packages/react-native-codegen/package.json +++ b/packages/react-native-codegen/package.json @@ -23,7 +23,7 @@ "nullthrows": "^1.1.1" }, "devDependencies": { - "@babel/core": "^7.0.0", + "@babel/core": "^7.14.0", "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", diff --git a/packages/react-native-codegen/src/cli/generators/generate-all.js b/packages/react-native-codegen/src/cli/generators/generate-all.js index 3aaca12c7a28ad..202c13eff9e43c 100644 --- a/packages/react-native-codegen/src/cli/generators/generate-all.js +++ b/packages/react-native-codegen/src/cli/generators/generate-all.js @@ -31,6 +31,7 @@ const schemaPath = args[0]; const libraryName = args[1]; const outputDirectory = args[2]; const packageName = args[3]; +const assumeNonnull = args[4] === 'true' || args[4] === 'True'; const schemaText = fs.readFileSync(schemaPath, 'utf-8'); @@ -48,7 +49,7 @@ try { } RNCodegen.generate( - {libraryName, schema, outputDirectory, packageName}, + {libraryName, schema, outputDirectory, packageName, assumeNonnull}, { generators: [ 'descriptors', diff --git a/packages/react-native-codegen/src/generators/RNCodegen.js b/packages/react-native-codegen/src/generators/RNCodegen.js index 34b2a390300bc5..1343c598c7de43 100644 --- a/packages/react-native-codegen/src/generators/RNCodegen.js +++ b/packages/react-native-codegen/src/generators/RNCodegen.js @@ -45,6 +45,7 @@ type Options = $ReadOnly<{ schema: SchemaType, outputDirectory: string, packageName?: string, // Some platforms have a notion of package, which should be configurable. + assumeNonnull: boolean, }>; type Generators = @@ -152,7 +153,7 @@ function checkFilesForChanges( module.exports = { generate( - {libraryName, schema, outputDirectory, packageName}: Options, + {libraryName, schema, outputDirectory, packageName, assumeNonnull}: Options, {generators, test}: Config, ): boolean { schemaValidator.validate(schema); @@ -160,7 +161,9 @@ module.exports = { const generatedFiles = []; for (const name of generators) { for (const generator of GENERATORS[name]) { - generatedFiles.push(...generator(libraryName, schema, packageName)); + generatedFiles.push( + ...generator(libraryName, schema, packageName, assumeNonnull), + ); } } diff --git a/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorH.js b/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorH.js index 2adf7ad393631d..7e670d98e386c3 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateComponentDescriptorH.js @@ -48,6 +48,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const fileName = 'ComponentDescriptors.h'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js index a2f42c8b3476f0..d664e3c2b8a38e 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js @@ -324,6 +324,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const fileName = 'RCTComponentViewHelpers.h'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js index b4f32f428079c7..4702ed5614b929 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js @@ -190,6 +190,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const moduleComponents: ComponentCollection = Object.keys(schema.modules) .map(moduleName => { diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js index 812783b947d3b3..65b4fc631087a1 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js @@ -239,6 +239,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const moduleComponents: ComponentCollection = Object.keys(schema.modules) .map(moduleName => { diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js b/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js index 39fc1ffc60fbb7..67536a0e35cde7 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js @@ -86,6 +86,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const fileName = 'Props.cpp'; const allImports: Set = new Set([ diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js index d218d809bc5bac..67619ddfdb858c 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js @@ -752,6 +752,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const fileName = 'Props.h'; diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js index 0e71cdbaa8673b..9f35f8e575464f 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js @@ -265,6 +265,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { // TODO: This doesn't support custom package name yet. const normalizedPackageName = 'com.facebook.react.viewmanagers'; diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js index 77781ec192b22a..fd4e891dea5d58 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js @@ -213,6 +213,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { // TODO: This doesn't support custom package name yet. const normalizedPackageName = 'com.facebook.react.viewmanagers'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateShadowNodeCpp.js b/packages/react-native-codegen/src/generators/components/GenerateShadowNodeCpp.js index f52444da89d64e..4c11da440c3806 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateShadowNodeCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateShadowNodeCpp.js @@ -45,6 +45,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const fileName = 'ShadowNodes.cpp'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateShadowNodeH.js b/packages/react-native-codegen/src/generators/components/GenerateShadowNodeH.js index b42da9bd557615..c976955ce0f36e 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateShadowNodeH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateShadowNodeH.js @@ -55,6 +55,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const fileName = 'ShadowNodes.h'; diff --git a/packages/react-native-codegen/src/generators/components/GenerateTests.js b/packages/react-native-codegen/src/generators/components/GenerateTests.js index ef5c3a47dfc2af..83a9f7b41a57ca 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateTests.js +++ b/packages/react-native-codegen/src/generators/components/GenerateTests.js @@ -140,6 +140,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const fileName = 'Tests.cpp'; const allImports = new Set([ diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js index 215b57846dc8a8..27eba9c32f1e7b 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js @@ -185,6 +185,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const nativeModules = getModules(schema); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index 2b50bd76b827c6..fe919e910cefb7 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -124,6 +124,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const nativeModules = getModules(schema); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js index 04c39024e166fc..e5d5ecb141b1f5 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js @@ -369,6 +369,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const files = new Map(); const nativeModules = getModules(schema); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js index 6f01ed4002edbf..53c0f702f48cd0 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js @@ -358,6 +358,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const nativeModules = getModules(schema); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js index 7c98c6e7f7b56f..4298a8d16d378b 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js @@ -98,6 +98,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean = false, ): FilesOutput { const nativeModules = getModules(schema); const modules = Object.keys(nativeModules) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js index eae698f52ace35..59a2ca93501ed8 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js @@ -51,10 +51,13 @@ namespace facebook { const HeaderFileTemplate = ({ moduleDeclarations, structInlineMethods, + assumeNonnull, }: $ReadOnly<{ moduleDeclarations: string, structInlineMethods: string, -}>) => `/** + assumeNonnull: boolean, +}>) => + `/** * ${'C'}opyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -81,9 +84,12 @@ const HeaderFileTemplate = ({ #import #import -${moduleDeclarations} -${structInlineMethods} -`; +` + + (assumeNonnull ? '\nNS_ASSUME_NONNULL_BEGIN\n' : '') + + moduleDeclarations + + '\n' + + structInlineMethods + + (assumeNonnull ? '\nNS_ASSUME_NONNULL_END\n' : '\n'); const SourceFileTemplate = ({ headerFileName, @@ -114,6 +120,7 @@ module.exports = { libraryName: string, schema: SchemaType, packageName?: string, + assumeNonnull: boolean, ): FilesOutput { const nativeModules = getModules(schema); @@ -194,6 +201,7 @@ module.exports = { const headerFile = HeaderFileTemplate({ moduleDeclarations: moduleDeclarations.join('\n'), structInlineMethods: structInlineMethods.join('\n'), + assumeNonnull, }); const sourceFileName = `${libraryName}-generated.mm`; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js index 4544348ccff62c..e73d46fa5e9ad2 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js +++ b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js @@ -25,6 +25,7 @@ describe('GenerateModuleHObjCpp', () => { fixtureName, fixture, 'com.facebook.fbreact.specs', + false, ); expect( new Map([[`${fixtureName}.h`, output.get(`${fixtureName}.h`)]]), diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js index 0d3fd81dd20694..c1a4feb400adba 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js +++ b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js @@ -25,6 +25,7 @@ describe('GenerateModuleMm', () => { fixtureName, fixture, 'com.facebook.fbreact.specs', + false, ); expect( new Map([ diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 9be8123e094d55..7a990ee1ee9bf2 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -4,7 +4,7 @@ PODS: - DoubleConversion (1.1.6) - FBLazyVector (1000.0.0) - FBReactNativeSpec (1000.0.0): - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-Core (= 1000.0.0) @@ -14,7 +14,7 @@ PODS: - Flipper-Folly (~> 2.5) - Flipper-RSocket (~> 1.3) - Flipper-DoubleConversion (1.1.7) - - Flipper-Folly (2.5.1): + - Flipper-Folly (2.5.3): - boost-for-react-native - Flipper-DoubleConversion - Flipper-Glog @@ -22,7 +22,7 @@ PODS: - OpenSSL-Universal (= 1.1.180) - Flipper-Glog (0.3.6) - Flipper-PeerTalk (0.0.4) - - Flipper-RSocket (1.3.0): + - Flipper-RSocket (1.3.1): - Flipper-Folly (~> 2.5) - FlipperKit (0.75.1): - FlipperKit/Core (= 0.75.1) @@ -56,26 +56,30 @@ PODS: - FlipperKit/SKIOSNetworkPlugin (0.75.1): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin + - fmt (6.2.1) - glog (0.3.5) - libevent (2.1.12) - OpenSSL-Universal (1.1.180) - - RCT-Folly (2020.01.13.00): + - RCT-Folly (2021.04.26.00): - boost-for-react-native - DoubleConversion + - fmt - glog - - RCT-Folly/Default (= 2020.01.13.00) - - RCT-Folly/Default (2020.01.13.00): + - RCT-Folly/Default (= 2021.04.26.00) + - RCT-Folly/Default (2021.04.26.00): - boost-for-react-native - DoubleConversion + - fmt - glog - - RCT-Folly/Fabric (2020.01.13.00): + - RCT-Folly/Fabric (2021.04.26.00): - boost-for-react-native - DoubleConversion + - fmt - glog - RCTRequired (1000.0.0) - RCTTypeSafety (1000.0.0): - FBLazyVector (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - React-Core (= 1000.0.0) - React (1000.0.0): @@ -94,7 +98,7 @@ PODS: - React-callinvoker (1000.0.0) - React-Core (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -103,7 +107,7 @@ PODS: - Yoga - React-Core/CoreModulesHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -112,7 +116,7 @@ PODS: - Yoga - React-Core/Default (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) - React-jsiexecutor (= 1000.0.0) @@ -120,7 +124,7 @@ PODS: - Yoga - React-Core/DevSupport (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default (= 1000.0.0) - React-Core/RCTWebSocket (= 1000.0.0) - React-cxxreact (= 1000.0.0) @@ -131,7 +135,7 @@ PODS: - Yoga - React-Core/RCTActionSheetHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -140,7 +144,7 @@ PODS: - Yoga - React-Core/RCTAnimationHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -149,7 +153,7 @@ PODS: - Yoga - React-Core/RCTBlobHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -158,7 +162,7 @@ PODS: - Yoga - React-Core/RCTImageHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -167,7 +171,7 @@ PODS: - Yoga - React-Core/RCTLinkingHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -176,7 +180,7 @@ PODS: - Yoga - React-Core/RCTNetworkHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -185,7 +189,7 @@ PODS: - Yoga - React-Core/RCTPushNotificationHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -194,7 +198,7 @@ PODS: - Yoga - React-Core/RCTSettingsHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -203,7 +207,7 @@ PODS: - Yoga - React-Core/RCTTextHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -212,7 +216,7 @@ PODS: - Yoga - React-Core/RCTVibrationHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -221,7 +225,7 @@ PODS: - Yoga - React-Core/RCTWebSocket (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/Default (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -230,7 +234,7 @@ PODS: - Yoga - React-CoreModules (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - RCTTypeSafety (= 1000.0.0) - React-Core/CoreModulesHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -240,14 +244,14 @@ PODS: - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-callinvoker (= 1000.0.0) - React-jsi (= 1000.0.0) - React-jsinspector (= 1000.0.0) - React-perflogger (= 1000.0.0) - React-runtimeexecutor (= 1000.0.0) - React-Fabric (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-Fabric/animations (= 1000.0.0) @@ -275,7 +279,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/animations (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -283,7 +287,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/attributedstring (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -291,7 +295,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/better (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -299,7 +303,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/componentregistry (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -307,7 +311,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/componentregistrynative (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -315,7 +319,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-Fabric/components/activityindicator (= 1000.0.0) @@ -338,7 +342,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/activityindicator (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -346,7 +350,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/image (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -354,7 +358,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/inputaccessory (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -362,7 +366,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/legacyviewmanagerinterop (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -370,7 +374,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/modal (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -378,7 +382,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/picker (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -386,7 +390,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/rncore (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -394,7 +398,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/root (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -402,7 +406,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/safeareaview (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -410,7 +414,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/scrollview (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -418,7 +422,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/slider (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -426,7 +430,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/text (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -434,7 +438,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/textinput (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -442,7 +446,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/unimplementedview (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -450,7 +454,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/components/view (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -459,7 +463,7 @@ PODS: - ReactCommon/turbomodule/core (= 1000.0.0) - Yoga - React-Fabric/config (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -467,7 +471,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/core (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -475,7 +479,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/debug_core (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -483,7 +487,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/debug_renderer (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -491,7 +495,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/imagemanager (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -500,7 +504,7 @@ PODS: - React-RCTImage (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/leakchecker (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -508,7 +512,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/mounting (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -516,7 +520,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/runtimescheduler (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -524,7 +528,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/scheduler (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -532,7 +536,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/telemetry (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -540,7 +544,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/templateprocessor (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -548,7 +552,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/textlayoutmanager (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-Fabric/uimanager @@ -557,7 +561,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/uimanager (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -565,7 +569,7 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-Fabric/utils (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-graphics (= 1000.0.0) @@ -573,27 +577,27 @@ PODS: - React-jsiexecutor (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-graphics (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - React-jsi (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-jsi/Default (= 1000.0.0) - React-jsi/Default (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-jsi/Fabric (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-jsiexecutor (1000.0.0): - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) - React-perflogger (= 1000.0.0) @@ -603,27 +607,27 @@ PODS: - React-Core/RCTActionSheetHeaders (= 1000.0.0) - React-RCTAnimation (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTAnimationHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTBlob (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/RCTBlobHeaders (= 1000.0.0) - React-Core/RCTWebSocket (= 1000.0.0) - React-jsi (= 1000.0.0) - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTFabric (1000.0.0): - - RCT-Folly/Fabric (= 2020.01.13.00) + - RCT-Folly/Fabric (= 2021.04.26.00) - React-Core (= 1000.0.0) - React-Fabric (= 1000.0.0) - React-RCTImage (= 1000.0.0) - React-RCTImage (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTImageHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -636,7 +640,7 @@ PODS: - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTNetworkHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -649,13 +653,13 @@ PODS: - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTSettings (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTSettingsHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTTest (1000.0.0): - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core (= 1000.0.0) - React-CoreModules (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -664,7 +668,7 @@ PODS: - React-Core/RCTTextHeaders (= 1000.0.0) - React-RCTVibration (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-Core/RCTVibrationHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) @@ -673,7 +677,7 @@ PODS: - ReactCommon/turbomodule/core (1000.0.0): - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-callinvoker (= 1000.0.0) - React-Core (= 1000.0.0) - React-cxxreact (= 1000.0.0) @@ -682,7 +686,7 @@ PODS: - ReactCommon/turbomodule/samples (1000.0.0): - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2021.04.26.00) - React-callinvoker (= 1000.0.0) - React-Core (= 1000.0.0) - React-cxxreact (= 1000.0.0) @@ -699,7 +703,7 @@ DEPENDENCIES: - FBReactNativeSpec (from `../../React/FBReactNativeSpec`) - Flipper (~> 0.75.1) - Flipper-DoubleConversion (= 1.1.7) - - Flipper-Folly (~> 2.5) + - Flipper-Folly (~> 2.5.3) - Flipper-Glog (= 0.3.6) - Flipper-PeerTalk (~> 0.0.4) - Flipper-RSocket (~> 1.3) @@ -763,6 +767,7 @@ SPEC REPOS: - Flipper-PeerTalk - Flipper-RSocket - FlipperKit + - fmt - libevent - OpenSSL-Universal - YogaKit @@ -840,45 +845,46 @@ SPEC CHECKSUMS: CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 FBLazyVector: b81a2b70c72d8b0aefb652cea22c11e9ffd02949 - FBReactNativeSpec: 8f209368616796eed1c127e6933dbfd7a117bc02 + FBReactNativeSpec: 9317c06a8fcc6ff3de6f045d45186523d4fe3458 Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 - Flipper-Folly: f7a3caafbd74bda4827954fd7a6e000e36355489 + Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 - Flipper-RSocket: 602921fee03edacf18f5d6f3d3594ba477f456e5 + Flipper-RSocket: 127954abe8b162fcaf68d2134d34dc2bd7076154 FlipperKit: 8a20b5c5fcf9436cac58551dc049867247f64b00 + fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 5337263514dd6f09803962437687240c5dc39aa4 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b - RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c + RCT-Folly: 8250e510cd9fde2f292ad258682264d4a1d38bff RCTRequired: af2d6080a4b9ba0885b28ca78879a92066c71cab - RCTTypeSafety: 1f6703f07db0433102c53a39b08c441bc74f726c + RCTTypeSafety: f5405e0143bb2addae97ce33e4c87d9284a48fe2 React: f64c9f6db5428717922a3292ba6a448615a2e143 React-callinvoker: c5d61e29df57793f0dc10ec2bc01c846f863e51f - React-Core: 836e8f265a3e09f5fb0825adfb6faadf463de80f - React-CoreModules: 3fc3961a1cf09c44fa89112f38d89d7d17f2226c - React-cxxreact: af0510bcae9cc043745bf4db10bbb1df6e1d4233 - React-Fabric: 7e588c340d211a421ff0c0b2dbe9a10459e300d7 - React-graphics: 463ffef0254d060a19b0aafbd823375f9ae45ce7 - React-jsi: 438d26574ec476e7721eecad31fdcded76d6afcc - React-jsiexecutor: 588df2ae1a96e056bacefc385034376532473a4b + React-Core: f5b65410a2ecdbb4560f23dc4525588390b0b3b1 + React-CoreModules: 818e75a3eb8f431be8fc3d8c8eb15206b3f52e81 + React-cxxreact: fa0884110d142f7e1600a86ae769d5fd43ec8a69 + React-Fabric: ee21f85af985320ca427353e95821a5b4d6f4f46 + React-graphics: 57cb7ea16c092a9953c96549a29b49d5e207c25c + React-jsi: 93fc7d193c0499a9b10157655e6f1e755f67b3d0 + React-jsiexecutor: 1e995bed2de8965703917c562fe35ec023a68ae5 React-jsinspector: 7d223826b0e7a61b3540c21b9eca2603b1d4e823 React-perflogger: fe66bd6d8b17ebcfdf0159bf41fe28d8035ac20c React-RCTActionSheet: 3131a0b9280aa0e51bdf54b3d79aecd8503db62c - React-RCTAnimation: bcdc239589d8d8f03ccd3ac08ce550c6306ca1fd - React-RCTBlob: c17a7eb29ce26af864230caf8504ca5878a39a83 - React-RCTFabric: 5a57c86ed7049e1f0e7bf8119f51119924cd6c85 - React-RCTImage: 54722ec7185c9d2b04866a030bdf790c9fcea445 + React-RCTAnimation: 6da530a8df8b3d33fb1f3743dcf1edeffa547cac + React-RCTBlob: ae75308b7097049c0c41319e171ba07a74783a81 + React-RCTFabric: 378a2432b9e2afae5b304f56fa4f3a0d802ca89d + React-RCTImage: ec3ee93093128e4acb3c5c4a7ead7d490154f124 React-RCTLinking: 559c9223212ab2824950883220582c5e29a6fcb2 - React-RCTNetwork: 61729312eb9450f73d0962d7784e01860dd081f2 + React-RCTNetwork: 26b845e36ae19fe497db021be2c4e7b1a69db21e React-RCTPushNotification: fafeb247db030c4d3f0a098d729e49f62ed32b3f - React-RCTSettings: 80f2296a3f5b94801ea45d2d31154289edd11861 - React-RCTTest: 0001858946dbe9f6f055efebb90164160b1ab15d + React-RCTSettings: a5e305535f7f32ee35d2d7741309e421aee2bef4 + React-RCTTest: dfeff675d31fbdf0596e87ca68011fcbb69fee42 React-RCTText: e9146b2c0550a83d1335bfe2553760070a2d75c7 - React-RCTVibration: aea79a107cfcbfcf9a55ca44b00cb00334d4d4ec + React-RCTVibration: 8501f7658810d80a2d7f1dcdaf2d257e3609e072 React-runtimeexecutor: 4b0c6eb341c7d3ceb5e2385cb0fdb9bf701024f3 - ReactCommon: 970d8ca9a8cac68c650c26a38e34d02132c65eea + ReactCommon: 19e102b75b4f384f2f017f3d6e973c78963d299d Yoga: c0d06f5380d34e939f55420669a60fe08b79bd75 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a diff --git a/packages/rn-tester/RCTTest/React-RCTTest.podspec b/packages/rn-tester/RCTTest/React-RCTTest.podspec index 8141f8d5526594..9b95f15bda12cf 100644 --- a/packages/rn-tester/RCTTest/React-RCTTest.podspec +++ b/packages/rn-tester/RCTTest/React-RCTTest.podspec @@ -17,7 +17,7 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2021.04.26.00' Pod::Spec.new do |s| s.name = "React-RCTTest" diff --git a/packages/rn-tester/RNTester/AppDelegate.mm b/packages/rn-tester/RNTester/AppDelegate.mm index 70c973bd8de7b4..dc5d65c1cfaddd 100644 --- a/packages/rn-tester/RNTester/AppDelegate.mm +++ b/packages/rn-tester/RNTester/AppDelegate.mm @@ -8,7 +8,7 @@ #import "AppDelegate.h" #ifndef RCT_USE_HERMES -#if __has_include() +#if __has_include() #define RCT_USE_HERMES 1 #else #define RCT_USE_HERMES 0 @@ -208,14 +208,14 @@ - (Class)getModuleClassFromName:(const char *)name { if (moduleClass == RCTImageLoader.class) { return [[moduleClass alloc] initWithRedirectDelegate:nil - loadersProvider:^NSArray> * { + loadersProvider:^NSArray> *(RCTModuleRegistry * moduleRegistry) { return @ [[RCTLocalAssetImageLoader new]]; } - decodersProvider:^NSArray> * { + decodersProvider:^NSArray> *(RCTModuleRegistry * moduleRegistry) { return @ [[RCTGIFImageDecoder new]]; }]; } else if (moduleClass == RCTNetworking.class) { - return [[moduleClass alloc] initWithHandlersProvider:^NSArray> * { + return [[moduleClass alloc] initWithHandlersProvider:^NSArray> *(RCTModuleRegistry * moduleRegistry) { return @[ [RCTHTTPRequestHandler new], [RCTDataRequestHandler new], diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj index e59f85b3e91717..2dacdccfc43ea1 100644 --- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj +++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj @@ -13,12 +13,11 @@ 2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */; }; 383889DA23A7398900D06C3E /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */; }; 3D2AFAF51D646CF80089D1A3 /* legacy_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */; }; + 53CC127E3B91B658F8ED740C /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7CD4B8D5BB59C1C0244513A4 /* libPods-RNTester.a */; }; 5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; }; 5CB07C9B226467E60039471C /* RNTesterTurboModuleProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */; }; - 682424F330D42708B52AA9A8 /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 88EFE7E584B42816405BA434 /* libPods-RNTester.a */; }; - 7B37A0C3E18EDC90CCD01CA2 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E6D00D70BA38970C7995F0A3 /* libPods-RNTesterIntegrationTests.a */; }; 8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; }; - DCB59B3E303512590BDA64B9 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6362DCCAA386FBF557077739 /* libPods-RNTesterUnitTests.a */; }; + B4547DAB66E8332C61BC76B9 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31B25925542FC132E61DD7FB /* libPods-RNTesterIntegrationTests.a */; }; E7C1241A22BEC44B00DA25C0 /* RNTesterIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */; }; E7DB20D122B2BAA6005AC45F /* RCTBundleURLProviderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB20A922B2BAA3005AC45F /* RCTBundleURLProviderTests.m */; }; E7DB20D222B2BAA6005AC45F /* RCTModuleInitNotificationRaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB20AA22B2BAA3005AC45F /* RCTModuleInitNotificationRaceTests.m */; }; @@ -57,6 +56,7 @@ E7DB216622B2F3EC005AC45F /* RCTRootViewIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB216122B2F3EC005AC45F /* RCTRootViewIntegrationTests.m */; }; E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7DB213022B2C649005AC45F /* JavaScriptCore.framework */; }; E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7DB218B22B41FCD005AC45F /* XCTest.framework */; }; + ECF793C6B9E3075ACB814AAD /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D7D48380EF1EAE280E156363 /* libPods-RNTesterUnitTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -77,30 +77,30 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 003E50F469503929A082A4F7 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = ""; }; 0CC3BE1A25DDB68A0033CAEB /* RNTester.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = RNTester.entitlements; path = RNTester/RNTester.entitlements; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* RNTester.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RNTester.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNTester/AppDelegate.h; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = ""; }; + 1DE2058CAA6A80823272AEBD /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = ""; }; 272E6B3B1BEA849E001FCF37 /* UpdatePropertiesExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UpdatePropertiesExampleView.h; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.h; sourceTree = ""; }; 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UpdatePropertiesExampleView.m; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.m; sourceTree = ""; }; 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FlexibleSizeExampleView.m; path = RNTester/NativeExampleViews/FlexibleSizeExampleView.m; sourceTree = ""; }; 27F441EA1BEBE5030039B79C /* FlexibleSizeExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FlexibleSizeExampleView.h; path = RNTester/NativeExampleViews/FlexibleSizeExampleView.h; sourceTree = ""; }; 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNTester/Images.xcassets; sourceTree = ""; }; - 34028D6B10F47E490042EB27 /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = ""; }; + 31B25925542FC132E61DD7FB /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = ""; }; 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "legacy_image@2x.png"; path = "RNTester/legacy_image@2x.png"; sourceTree = ""; }; - 5BEC8567F3741044B6A5EFC5 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Pods/Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = ""; }; 5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = ""; }; 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RNTesterTurboModuleProvider.mm; path = RNTester/RNTesterTurboModuleProvider.mm; sourceTree = ""; }; 5CB07C9A226467E60039471C /* RNTesterTurboModuleProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNTesterTurboModuleProvider.h; path = RNTester/RNTesterTurboModuleProvider.h; sourceTree = ""; }; - 6362DCCAA386FBF557077739 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 7D51F73F0DA20287418D98BD /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = ""; }; + 7CD4B8D5BB59C1C0244513A4 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNTester/LaunchScreen.storyboard; sourceTree = ""; }; - 88EFE7E584B42816405BA434 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 972A459EE6CF8CC63531A088 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = ""; }; - 98233960D1D6A1977D1C7EAF /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = ""; }; - E6D00D70BA38970C7995F0A3 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 889A7AA476F27B8B1618D4D7 /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = ""; }; + BF8238897248BA8B3272C0BE /* Pods-RNTesterUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.release.xcconfig"; sourceTree = ""; }; + C91FACC766DA32F8FE5F3184 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = ""; }; + D7D48380EF1EAE280E156363 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E771AEEA22B44E3100EA1189 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTesterIntegrationTests.m; sourceTree = ""; }; E7DB209F22B2BA84005AC45F /* RNTesterUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNTesterUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -173,7 +173,7 @@ E7DB216022B2F3EC005AC45F /* RNTesterSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTesterSnapshotTests.m; sourceTree = ""; }; E7DB216122B2F3EC005AC45F /* RCTRootViewIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootViewIntegrationTests.m; sourceTree = ""; }; E7DB218B22B41FCD005AC45F /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = XCTest.framework; sourceTree = DEVELOPER_DIR; }; - E9618482EC8608D4872A6E28 /* Pods-RNTesterUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.release.xcconfig"; sourceTree = ""; }; + FAF65151020A434994A87414 /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -181,7 +181,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 682424F330D42708B52AA9A8 /* libPods-RNTester.a in Frameworks */, + 53CC127E3B91B658F8ED740C /* libPods-RNTester.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -191,7 +191,7 @@ files = ( E7DB213122B2C649005AC45F /* JavaScriptCore.framework in Frameworks */, E7DB213222B2C67D005AC45F /* libOCMock.a in Frameworks */, - DCB59B3E303512590BDA64B9 /* libPods-RNTesterUnitTests.a in Frameworks */, + ECF793C6B9E3075ACB814AAD /* libPods-RNTesterUnitTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -201,7 +201,7 @@ files = ( E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */, E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */, - 7B37A0C3E18EDC90CCD01CA2 /* libPods-RNTesterIntegrationTests.a in Frameworks */, + B4547DAB66E8332C61BC76B9 /* libPods-RNTesterIntegrationTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -247,6 +247,20 @@ name = NativeExampleViews; sourceTree = ""; }; + 2D7E30913682C21F42E0EFFA /* Pods */ = { + isa = PBXGroup; + children = ( + 1DE2058CAA6A80823272AEBD /* Pods-RNTester.debug.xcconfig */, + C91FACC766DA32F8FE5F3184 /* Pods-RNTester.release.xcconfig */, + 003E50F469503929A082A4F7 /* Pods-RNTesterIntegrationTests.debug.xcconfig */, + 889A7AA476F27B8B1618D4D7 /* Pods-RNTesterIntegrationTests.release.xcconfig */, + FAF65151020A434994A87414 /* Pods-RNTesterUnitTests.debug.xcconfig */, + BF8238897248BA8B3272C0BE /* Pods-RNTesterUnitTests.release.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 2DE7E7D81FB2A4F3009E225D /* Frameworks */ = { isa = PBXGroup; children = ( @@ -272,26 +286,13 @@ E7DB211822B2BD53005AC45F /* libReact-RCTText.a */, E7DB211A22B2BD53005AC45F /* libReact-RCTVibration.a */, E7DB212222B2BD53005AC45F /* libyoga.a */, - 88EFE7E584B42816405BA434 /* libPods-RNTester.a */, - E6D00D70BA38970C7995F0A3 /* libPods-RNTesterIntegrationTests.a */, - 6362DCCAA386FBF557077739 /* libPods-RNTesterUnitTests.a */, + 7CD4B8D5BB59C1C0244513A4 /* libPods-RNTester.a */, + 31B25925542FC132E61DD7FB /* libPods-RNTesterIntegrationTests.a */, + D7D48380EF1EAE280E156363 /* libPods-RNTesterUnitTests.a */, ); name = Frameworks; sourceTree = ""; }; - 571A4A20844C3BA40A3D302B /* Pods */ = { - isa = PBXGroup; - children = ( - 98233960D1D6A1977D1C7EAF /* Pods-RNTester.debug.xcconfig */, - 5BEC8567F3741044B6A5EFC5 /* Pods-RNTester.release.xcconfig */, - 972A459EE6CF8CC63531A088 /* Pods-RNTesterIntegrationTests.debug.xcconfig */, - 7D51F73F0DA20287418D98BD /* Pods-RNTesterIntegrationTests.release.xcconfig */, - 34028D6B10F47E490042EB27 /* Pods-RNTesterUnitTests.debug.xcconfig */, - E9618482EC8608D4872A6E28 /* Pods-RNTesterUnitTests.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; 680759612239798500290469 /* Fabric */ = { isa = PBXGroup; children = ( @@ -307,7 +308,7 @@ E7DB215422B2F332005AC45F /* RNTesterIntegrationTests */, 83CBBA001A601CBA00E9B192 /* Products */, 2DE7E7D81FB2A4F3009E225D /* Frameworks */, - 571A4A20844C3BA40A3D302B /* Pods */, + 2D7E30913682C21F42E0EFFA /* Pods */, ); indentWidth = 2; sourceTree = ""; @@ -401,14 +402,14 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNTester" */; buildPhases = ( - F9CB97B0D9633939D43E75E0 /* [CP] Check Pods Manifest.lock */, + 27AC6FB824D3421A7BA1C162 /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */, 5CF0FD27207FC6EC00C13D65 /* Start Metro */, - CD2B49A7F80C8171E7A5B233 /* [CP] Copy Pods Resources */, - FCBC860F39D3E385BA7C6FF7 /* [CP] Embed Pods Frameworks */, + 7F1F8D267AA3C5E850B51DD3 /* [CP] Embed Pods Frameworks */, + 8D3C37296BA387DCE6709551 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -423,11 +424,11 @@ isa = PBXNativeTarget; buildConfigurationList = E7DB20A622B2BA84005AC45F /* Build configuration list for PBXNativeTarget "RNTesterUnitTests" */; buildPhases = ( - 64C8C8D2305EEDFDE304A0E6 /* [CP] Check Pods Manifest.lock */, + 4D92FAF33190737DB209312C /* [CP] Check Pods Manifest.lock */, E7DB209B22B2BA84005AC45F /* Sources */, E7DB209C22B2BA84005AC45F /* Frameworks */, E7DB209D22B2BA84005AC45F /* Resources */, - 71ADC6D58A978687B97C823F /* [CP] Copy Pods Resources */, + B3F9D94DBF04ED34B5530093 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -443,11 +444,11 @@ isa = PBXNativeTarget; buildConfigurationList = E7DB215A22B2F332005AC45F /* Build configuration list for PBXNativeTarget "RNTesterIntegrationTests" */; buildPhases = ( - 56D84768A7BBB2750D674CF3 /* [CP] Check Pods Manifest.lock */, + 6A89657ACC79694D26C7FCA5 /* [CP] Check Pods Manifest.lock */, E7DB214F22B2F332005AC45F /* Sources */, E7DB215022B2F332005AC45F /* Frameworks */, E7DB215122B2F332005AC45F /* Resources */, - 87FAF758B87BEA78F26A2B92 /* [CP] Copy Pods Resources */, + 8F1EA6A66F49ED8EB26D6EC8 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -526,7 +527,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 56D84768A7BBB2750D674CF3 /* [CP] Check Pods Manifest.lock */ = { + 27AC6FB824D3421A7BA1C162 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -541,48 +542,48 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTester-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 5CF0FD27207FC6EC00C13D65 /* Start Metro */ = { + 4D92FAF33190737DB209312C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "Start Metro"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RNTesterUnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../../scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 64C8C8D2305EEDFDE304A0E6 /* [CP] Check Pods Manifest.lock */ = { + 5CF0FD27207FC6EC00C13D65 /* Start Metro */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( ); + name = "Start Metro"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTesterUnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../../scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; showEnvVarsInLog = 0; }; 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */ = { @@ -599,41 +600,46 @@ shellPath = /bin/sh; shellScript = "set -e\n\nexport NODE_BINARY=node\nexport PROJECT_ROOT=\"$SRCROOT/../../\"\nexport SOURCEMAP_FILE=../sourcemap.ios.map\n# export FORCE_BUNDLING=true\n\"$SRCROOT/../../scripts/react-native-xcode.sh\" $SRCROOT/../../packages/rn-tester/js/RNTesterApp.ios.js\n"; }; - 71ADC6D58A978687B97C823F /* [CP] Copy Pods Resources */ = { + 6A89657ACC79694D26C7FCA5 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 87FAF758B87BEA78F26A2B92 /* [CP] Copy Pods Resources */ = { + 7F1F8D267AA3C5E850B51DD3 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - CD2B49A7F80C8171E7A5B233 /* [CP] Copy Pods Resources */ = { + 8D3C37296BA387DCE6709551 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -650,39 +656,38 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources.sh\"\n"; showEnvVarsInLog = 0; }; - F9CB97B0D9633939D43E75E0 /* [CP] Check Pods Manifest.lock */ = { + 8F1EA6A66F49ED8EB26D6EC8 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-checkManifestLockResult.txt", + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - FCBC860F39D3E385BA7C6FF7 /* [CP] Embed Pods Frameworks */ = { + B3F9D94DBF04ED34B5530093 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -766,7 +771,7 @@ /* Begin XCBuildConfiguration section */ 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 98233960D1D6A1977D1C7EAF /* Pods-RNTester.debug.xcconfig */; + baseConfigurationReference = 1DE2058CAA6A80823272AEBD /* Pods-RNTester.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = RNTester/RNTester.entitlements; @@ -799,7 +804,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5BEC8567F3741044B6A5EFC5 /* Pods-RNTester.release.xcconfig */; + baseConfigurationReference = C91FACC766DA32F8FE5F3184 /* Pods-RNTester.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = RNTester/RNTester.entitlements; @@ -993,7 +998,7 @@ }; E7DB20A722B2BA84005AC45F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 34028D6B10F47E490042EB27 /* Pods-RNTesterUnitTests.debug.xcconfig */; + baseConfigurationReference = FAF65151020A434994A87414 /* Pods-RNTesterUnitTests.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -1029,7 +1034,7 @@ }; E7DB20A822B2BA84005AC45F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E9618482EC8608D4872A6E28 /* Pods-RNTesterUnitTests.release.xcconfig */; + baseConfigurationReference = BF8238897248BA8B3272C0BE /* Pods-RNTesterUnitTests.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -1065,7 +1070,7 @@ }; E7DB215B22B2F332005AC45F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 972A459EE6CF8CC63531A088 /* Pods-RNTesterIntegrationTests.debug.xcconfig */; + baseConfigurationReference = 003E50F469503929A082A4F7 /* Pods-RNTesterIntegrationTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; @@ -1103,7 +1108,7 @@ }; E7DB215C22B2F332005AC45F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7D51F73F0DA20287418D98BD /* Pods-RNTesterIntegrationTests.release.xcconfig */; + baseConfigurationReference = 889A7AA476F27B8B1618D4D7 /* Pods-RNTesterIntegrationTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; diff --git a/packages/rn-tester/RNTesterUnitTests/RCTBlobManagerTests.m b/packages/rn-tester/RNTesterUnitTests/RCTBlobManagerTests.m index 7b10ce9178e765..7e88f3e7381e90 100644 --- a/packages/rn-tester/RNTesterUnitTests/RCTBlobManagerTests.m +++ b/packages/rn-tester/RNTesterUnitTests/RCTBlobManagerTests.m @@ -26,6 +26,7 @@ - (void)setUp _module = [RCTBlobManager new]; [_module setValue:nil forKey:@"bridge"]; + [_module initialize]; NSInteger size = 120; _data = [NSMutableData dataWithCapacity:size]; for (NSInteger i = 0; i < size / 4; i++) { diff --git a/packages/rn-tester/RNTesterUnitTests/RCTEventDispatcherTests.m b/packages/rn-tester/RNTesterUnitTests/RCTEventDispatcherTests.m index d1b5dee1c1ccf4..7250f25d34b381 100644 --- a/packages/rn-tester/RNTesterUnitTests/RCTEventDispatcherTests.m +++ b/packages/rn-tester/RNTesterUnitTests/RCTEventDispatcherTests.m @@ -75,6 +75,7 @@ @implementation RCTEventDispatcherTests { id _bridge; RCTEventDispatcher *_eventDispatcher; + RCTCallableJSModules *_callableJSModules; NSString *_eventName; NSDictionary *_body; @@ -89,8 +90,13 @@ - (void)setUp _bridge = [OCMockObject mockForClass:[RCTDummyBridge class]]; + _callableJSModules = [RCTCallableJSModules new]; + [_callableJSModules setBridge:_bridge]; + _eventDispatcher = [RCTEventDispatcher new]; [_eventDispatcher setValue:_bridge forKey:@"bridge"]; + [_eventDispatcher setValue:_callableJSModules forKey:@"callableJSModules"]; + [_eventDispatcher initialize]; _eventName = RCTNormalizeInputEventName(@"sampleEvent"); _body = @{ @"foo": @"bar" }; @@ -161,8 +167,8 @@ - (void)testRunningTheDispatchedBlockResultInANewOneBeingEnqueued [_bridge verify]; // eventsEmittingBlock would be called when js is no longer busy, which will result in emitting events - [[_bridge expect] enqueueJSCall:[[_testEvent class] moduleDotMethod] - args:[_testEvent arguments]]; + [self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] + args:[_testEvent arguments]]; eventsEmittingBlock(); [_bridge verify]; @@ -179,8 +185,8 @@ - (void)testBasicCoalescingReturnsLastEvent eventsEmittingBlock = block; return YES; }] queue:RCTJSThread]; - [[_bridge expect] enqueueJSCall:[[_testEvent class] moduleDotMethod] - args:[_testEvent arguments]]; + [self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] + args:[_testEvent arguments]]; RCTTestEvent *ignoredEvent = [[RCTTestEvent alloc] initWithViewTag:nil eventName:_eventName @@ -206,10 +212,10 @@ - (void)testDifferentEventTypesDontCoalesce eventsEmittingBlock = block; return YES; }] queue:RCTJSThread]; - [[_bridge expect] enqueueJSCall:[[_testEvent class] moduleDotMethod] - args:[firstEvent arguments]]; - [[_bridge expect] enqueueJSCall:[[_testEvent class] moduleDotMethod] - args:[_testEvent arguments]]; + [self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] + args:[firstEvent arguments]]; + [self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] + args:[_testEvent arguments]]; [_eventDispatcher sendEvent:firstEvent]; @@ -235,10 +241,10 @@ - (void)testDifferentViewTagsDontCoalesce eventsEmittingBlock = block; return YES; }] queue:RCTJSThread]; - [[_bridge expect] enqueueJSCall:[[firstEvent class] moduleDotMethod] - args:[firstEvent arguments]]; - [[_bridge expect] enqueueJSCall:[[secondEvent class] moduleDotMethod] - args:[secondEvent arguments]]; + [self _expectBridgeJSCall:[[firstEvent class] moduleDotMethod] + args:[firstEvent arguments]]; + [self _expectBridgeJSCall:[[secondEvent class] moduleDotMethod] + args:[secondEvent arguments]]; [_eventDispatcher sendEvent:firstEvent]; @@ -265,10 +271,10 @@ - (void)testSameEventTypesWithDifferentCoalesceKeysDontCoalesce eventsEmittingBlock = block; return YES; }] queue:RCTJSThread]; - [[_bridge expect] enqueueJSCall:[[_testEvent class] moduleDotMethod] - args:[firstEvent arguments]]; - [[_bridge expect] enqueueJSCall:[[_testEvent class] moduleDotMethod] - args:[secondEvent arguments]]; + [self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] + args:[firstEvent arguments]]; + [self _expectBridgeJSCall:[[_testEvent class] moduleDotMethod] + args:[secondEvent arguments]]; [_eventDispatcher sendEvent:firstEvent]; @@ -284,4 +290,15 @@ - (void)testSameEventTypesWithDifferentCoalesceKeysDontCoalesce [_bridge verify]; } +-(void)_expectBridgeJSCall:(NSString *)moduleDotMethod args:(NSArray *)args +{ + NSArray *const components = [moduleDotMethod componentsSeparatedByString:@"."]; + NSString *const moduleName = components[0]; + NSString *const methodName = components[1]; + [[_bridge expect] enqueueJSCall:moduleName + method:methodName + args:args + completion:NULL]; +} + @end diff --git a/packages/rn-tester/RNTesterUnitTests/RCTModuleInitNotificationRaceTests.m b/packages/rn-tester/RNTesterUnitTests/RCTModuleInitNotificationRaceTests.m index 781b74bb74af5d..67aef5d42ae142 100644 --- a/packages/rn-tester/RNTesterUnitTests/RCTModuleInitNotificationRaceTests.m +++ b/packages/rn-tester/RNTesterUnitTests/RCTModuleInitNotificationRaceTests.m @@ -15,6 +15,7 @@ #import #import #import +#import @interface RCTTestViewManager : RCTViewManager @end @@ -36,7 +37,7 @@ @implementation RCTTestViewManager @end -@interface RCTNotificationObserverModule : NSObject +@interface RCTNotificationObserverModule : NSObject @property (nonatomic, assign) BOOL didDetectViewManagerInit; @@ -48,9 +49,8 @@ @implementation RCTNotificationObserverModule RCT_EXPORT_MODULE() -- (void)setBridge:(RCTBridge *)bridge +- (void)initialize { - _bridge = bridge; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didInitViewManager:) name:RCTDidInitializeModuleNotification object:nil]; } diff --git a/packages/rn-tester/RNTesterUnitTests/RCTModuleInitTests.m b/packages/rn-tester/RNTesterUnitTests/RCTModuleInitTests.m index 3056bc5f8f654d..c0899183142d35 100644 --- a/packages/rn-tester/RNTesterUnitTests/RCTModuleInitTests.m +++ b/packages/rn-tester/RNTesterUnitTests/RCTModuleInitTests.m @@ -14,6 +14,7 @@ #import #import #import +#import @interface RCTTestInjectedModule : NSObject @end @@ -52,7 +53,7 @@ - (id)init @end -@interface RCTTestCustomSetBridgeModule : NSObject +@interface RCTTestCustomSetBridgeModule : NSObject @property (nonatomic, assign) BOOL setBridgeOnMainQueue; @@ -65,9 +66,8 @@ @implementation RCTTestCustomSetBridgeModule RCT_EXPORT_MODULE() -- (void)setBridge:(RCTBridge *)bridge +- (void)initialize { - _bridge = bridge; _setBridgeOnMainQueue = RCTIsMainQueue(); } diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityAndroidExample.android.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityAndroidExample.android.js index e35299d58a8803..3f807fdc5982b1 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityAndroidExample.android.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityAndroidExample.android.js @@ -5,20 +5,15 @@ * LICENSE file in the root directory of this source tree. * * @format + * @flow strict-local */ 'use strict'; const React = require('react'); -const { - StyleSheet, - Text, - View, - TouchableWithoutFeedback, -} = require('react-native'); - -const RNTesterBlock = require('../../components/RNTesterBlock'); -const RNTesterPage = require('../../components/RNTesterPage'); +import RNTesterBlock from '../../components/RNTesterBlock'; +import RNTesterPage from '../../components/RNTesterPage'; +import {StyleSheet, Text, View, TouchableWithoutFeedback} from 'react-native'; const importantForAccessibilityValues = [ 'auto', @@ -27,8 +22,17 @@ const importantForAccessibilityValues = [ 'no-hide-descendants', ]; -class AccessibilityAndroidExample extends React.Component { - state = { +type AccessibilityAndroidExampleState = { + count: number, + backgroundImportantForAcc: number, + forgroundImportantForAcc: number, +}; + +class AccessibilityAndroidExample extends React.Component< + {}, + AccessibilityAndroidExampleState, +> { + state: AccessibilityAndroidExampleState = { count: 0, backgroundImportantForAcc: 0, forgroundImportantForAcc: 0, @@ -52,7 +56,7 @@ class AccessibilityAndroidExample extends React.Component { }); }; - render() { + render(): React.Node { return ( @@ -61,22 +65,14 @@ class AccessibilityAndroidExample extends React.Component { Click me - - Clicked {this.state.count} times - + + Clicked {this.state.count} times + - + Hello @@ -153,6 +149,14 @@ class AccessibilityAndroidExample extends React.Component { } const styles = StyleSheet.create({ + touchableContainer: { + position: 'absolute', + left: 10, + top: 10, + right: 10, + height: 100, + backgroundColor: 'green', + }, embedded: { backgroundColor: 'yellow', padding: 10, diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js index 3f6611d05fc75d..40613c0c80bde5 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format + * @flow */ 'use strict'; @@ -21,8 +22,11 @@ const { TouchableWithoutFeedback, Alert, StyleSheet, + Slider, + Picker, Platform, } = require('react-native'); +import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter'; const RNTesterBlock = require('../../components/RNTesterBlock'); @@ -53,6 +57,10 @@ const styles = StyleSheet.create({ resizeMode: 'contain', marginRight: 10, }, + disabledImage: { + width: 120, + height: 120, + }, containerAlignCenter: { display: 'flex', flexDirection: 'column', @@ -60,8 +68,8 @@ const styles = StyleSheet.create({ }, }); -class AccessibilityExample extends React.Component { - render() { +class AccessibilityExample extends React.Component<{}> { + render(): React.Node { return ( @@ -101,7 +109,7 @@ class AccessibilityExample extends React.Component { {/* Android screen readers will say the accessibility hint instead of the text - since the view doesn't have a label. */} + since the view doesn't have a label. */} This is text one. @@ -155,6 +163,18 @@ class AccessibilityExample extends React.Component { + + Alert.alert('Disabled Button has been pressed!')} + accessibilityLabel={'You are pressing Disabled TouchableOpacity'} + accessibilityState={{disabled: true}}> + + + I am disabled. Clicking me will not trigger any action. + + + + { state = { checkboxState: true, }; @@ -212,7 +237,12 @@ class CheckboxExample extends React.Component { } } -class SwitchExample extends React.Component { +class SwitchExample extends React.Component< + {}, + { + switchState: boolean, + }, +> { state = { switchState: true, }; @@ -239,18 +269,27 @@ class SwitchExample extends React.Component { } } -class SelectionExample extends React.Component { - constructor(props) { +class SelectionExample extends React.Component< + {}, + { + isSelected: boolean, + isEnabled: boolean, + }, +> { + constructor(props: {}) { super(props); - this.selectableElement = React.createRef(); + this.selectableElement = createRef(); } + selectableElement: { + current: React.ElementRef | null, + }; state = { isSelected: true, isEnabled: false, }; - render() { + render(): React.Node { const {isSelected, isEnabled} = this.state; let accessibilityHint = 'click me to select'; if (isSelected) { @@ -311,7 +350,12 @@ class SelectionExample extends React.Component { } } -class ExpandableElementExample extends React.Component { +class ExpandableElementExample extends React.Component< + {}, + { + expandState: boolean, + }, +> { state = { expandState: false, }; @@ -337,7 +381,14 @@ class ExpandableElementExample extends React.Component { } } -class NestedCheckBox extends React.Component { +class NestedCheckBox extends React.Component< + {}, + { + checkbox1: boolean | 'mixed', + checkbox2: boolean | 'mixed', + checkbox3: boolean | 'mixed', + }, +> { state = { checkbox1: false, checkbox2: false, @@ -446,7 +497,7 @@ class NestedCheckBox extends React.Component { } class AccessibilityRoleAndStateExample extends React.Component<{}> { - render() { + render(): React.Node { return ( { } } -class AccessibilityActionsExample extends React.Component { - render() { +class AccessibilityActionsExample extends React.Component<{}> { + render(): React.Node { return ( @@ -614,7 +665,7 @@ class AccessibilityActionsExample extends React.Component { - + + + + + + + + + Animation Type + + + + + + {this.renderSwitch()} + {this.renderPickers()} + + + ); + } + renderPickers(): React.Node { + if (Platform.isTV) { + return null; + } + return ( + + + Presentation style + + this.setState({presentationStyle}) + } + itemStyle={styles.pickerItem}> + + + + + + + + + + Supported orientations + + this.setState({selectedSupportedOrientation: i.toString()}) + } + itemStyle={styles.pickerItem}> + + + + + + + + + + + Actions + {Platform.OS === 'ios' ? ( + this.setState({action})} + itemStyle={styles.pickerItem}> + + + + + ) : ( + this.setState({action})} + itemStyle={styles.pickerItem}> + + + + )} + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + padding: 20, + }, + innerContainer: { + borderRadius: 10, + alignItems: 'center', + }, + row: { + alignItems: 'center', + flex: 1, + flexDirection: 'row', + marginBottom: 20, + }, + rowTitle: { + flex: 1, + fontWeight: 'bold', + }, + button: { + borderRadius: 5, + flexGrow: 1, + height: 44, + alignSelf: 'stretch', + justifyContent: 'center', + overflow: 'hidden', + }, + buttonText: { + fontSize: 18, + margin: 5, + textAlign: 'center', + }, + modalButton: { + marginTop: 10, + }, + pickerItem: { + fontSize: 16, + }, + ScrollView: { + paddingTop: 10, + paddingBottom: 100, + }, +}); + +export default ({ + title: 'Modal Presentation', + name: 'basic', + description: 'Modals can be presented with or without animation', + render: (): React.Node => , +}: RNTesterExampleModuleItem); diff --git a/packages/rn-tester/js/examples/Modal/ModalExample.js b/packages/rn-tester/js/examples/Modal/ModalExample.js index 1cfae6d4d93f25..1c0405029ff829 100644 --- a/packages/rn-tester/js/examples/Modal/ModalExample.js +++ b/packages/rn-tester/js/examples/Modal/ModalExample.js @@ -4,347 +4,21 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format * @flow strict-local + * @format */ -'use strict'; - -const React = require('react'); - -const { - Modal, - Picker, - Platform, - StyleSheet, - Switch, - Text, - TouchableHighlight, - View, - ScrollView, -} = require('react-native'); - -const Item = Picker.Item; - -exports.displayName = (undefined: ?string); -exports.framework = 'React'; -exports.title = 'Modal'; -exports.category = 'UI'; -exports.documentationURL = 'https://reactnative.dev/docs/modal'; -exports.description = 'Component for presenting modal views.'; - -class Button extends React.Component<$FlowFixMeProps, $FlowFixMeState> { - state = { - active: false, - }; - - _onHighlight = () => { - this.setState({active: true}); - }; - - _onUnhighlight = () => { - this.setState({active: false}); - }; - - render() { - const colorStyle = { - color: this.state.active ? '#fff' : '#000', - }; - return ( - - - {this.props.children} - - - ); - } -} - -const supportedOrientationsPickerValues = [ - ['portrait'], - ['landscape'], - ['landscape-left'], - ['portrait', 'landscape-right'], - ['portrait', 'landscape'], - [], -]; - -class ModalExample extends React.Component<{...}, $FlowFixMeState> { - state = { - animationType: 'none', - modalVisible: false, - transparent: false, - hardwareAccelerated: false, - statusBarTranslucent: false, - presentationStyle: 'fullScreen', - selectedSupportedOrientation: '0', - currentOrientation: 'unknown', - action: '', - }; - - _setModalVisible = visible => { - this.setState({modalVisible: visible}); - }; - - _setAnimationType = type => { - this.setState({animationType: type}); - }; - - _toggleTransparent = () => { - this.setState({transparent: !this.state.transparent}); - }; - - _toggleHardwareAccelerated = () => { - this.setState({hardwareAccelerated: !this.state.hardwareAccelerated}); - }; - - _toggleStatusBarTranslucent = () => { - this.setState({statusBarTranslucent: !this.state.statusBarTranslucent}); - }; - - renderSwitch() { - if (Platform.isTV) { - return null; - } - if (Platform.OS === 'android') { - return ( - <> - Hardware Accelerated - - Status Bar Translucent - - Transparent - - - ); - } - return ( - - ); - } - - render() { - const modalBackgroundStyle = { - backgroundColor: this.state.transparent - ? 'rgba(0, 0, 0, 0.5)' - : '#f5fcff', - }; - const innerContainerTransparentStyle = this.state.transparent - ? {backgroundColor: '#fff', padding: 20} - : null; - const activeButtonStyle = { - backgroundColor: '#ddd', - }; - - return ( - - this._setModalVisible(false)} - supportedOrientations={ - supportedOrientationsPickerValues[ - Number(this.state.selectedSupportedOrientation) - ] - } - onOrientationChange={evt => - this.setState({currentOrientation: evt.nativeEvent.orientation}) - } - onDismiss={() => { - if (this.state.action === 'onDismiss') alert(this.state.action); - }} - onShow={() => { - if (this.state.action === 'onShow') alert(this.state.action); - }}> - - - - This modal was presented{' '} - {this.state.animationType === 'none' ? 'without' : 'with'}{' '} - animation. - - - It is currently displayed in {this.state.currentOrientation}{' '} - mode. - - - - - - - Animation Type - - - - - - {this.renderSwitch()} - {this.renderPickers()} - - - ); - } - renderPickers() { - if (Platform.isTV) { - return null; - } - return ( - - - Presentation style - - this.setState({presentationStyle}) - } - itemStyle={styles.pickerItem}> - - - - - - - - - - Supported orientations - - this.setState({selectedSupportedOrientation: i.toString()}) - } - itemStyle={styles.pickerItem}> - - - - - - - - - - - Actions - {Platform.OS === 'ios' ? ( - this.setState({action})} - itemStyle={styles.pickerItem}> - - - - - ) : ( - this.setState({action})} - itemStyle={styles.pickerItem}> - - - - )} - - - ); - } -} - -exports.examples = [ - { - title: 'Modal Presentation', - name: 'basic', - description: 'Modals can be presented with or without animation', - render: (): React.Node => , - }, -]; - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - padding: 20, - }, - innerContainer: { - borderRadius: 10, - alignItems: 'center', - }, - row: { - alignItems: 'center', - flex: 1, - flexDirection: 'row', - marginBottom: 20, - }, - rowTitle: { - flex: 1, - fontWeight: 'bold', - }, - button: { - borderRadius: 5, - flexGrow: 1, - height: 44, - alignSelf: 'stretch', - justifyContent: 'center', - overflow: 'hidden', - }, - buttonText: { - fontSize: 18, - margin: 5, - textAlign: 'center', - }, - modalButton: { - marginTop: 10, - }, - pickerItem: { - fontSize: 16, - }, - ScrollView: { - paddingTop: 10, - paddingBottom: 100, - }, -}); +import ModalCustomizable from './ModalCustomizable'; +import ModalOnShow from './ModalOnShow'; +import type {RNTesterExampleModuleItem} from '../../types/RNTesterTypes'; + +export const displayName = (undefined: ?string); +export const framework = 'React'; +export const title = 'Modal'; +export const category = 'UI'; +export const documentationURL = 'https://reactnative.dev/docs/modal'; +export const description = 'Component for presenting modal views.'; +export const examples = ([ + ModalCustomizable, + ModalOnShow, +]: Array); diff --git a/packages/rn-tester/js/examples/Modal/ModalOnShow.js b/packages/rn-tester/js/examples/Modal/ModalOnShow.js new file mode 100644 index 00000000000000..5f40eeab2889a8 --- /dev/null +++ b/packages/rn-tester/js/examples/Modal/ModalOnShow.js @@ -0,0 +1,137 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import * as React from 'react'; +import {Modal, Pressable, StyleSheet, Text, View} from 'react-native'; +import type {RNTesterExampleModuleItem} from '../../types/RNTesterTypes'; + +function ModalOnShowOnDismiss(): React.Node { + const [modalShowComponent, setModalShowComponent] = React.useState(true); + const [modalVisible, setModalVisible] = React.useState(false); + const [onShowCount, setOnShowCount] = React.useState(0); + const [onDismissCount, setOnDismissCount] = React.useState(0); + + return ( + + {modalShowComponent && ( + { + setOnShowCount(onShowCount + 1); + }} + onDismiss={() => { + setOnDismissCount(onDismissCount + 1); + }} + onRequestClose={() => { + setModalVisible(false); + }}> + + + + onShow is called {onShowCount} times + + + onDismiss is called {onDismissCount} times + + setModalVisible(false)}> + + Hide modal by setting visible to false + + + setModalShowComponent(false)}> + + Hide modal by removing component + + + + + + )} + onShow is called {onShowCount} times + + onDismiss is called {onDismissCount} times + + { + setModalShowComponent(true); + setModalVisible(true); + }}> + + Show Modal + + + + ); +} + +const styles = StyleSheet.create({ + container: { + display: 'flex', + alignItems: 'center', + paddingVertical: 30, + }, + centeredView: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + modalBackdrop: { + backgroundColor: 'rgba(0, 0, 0, 0.5)', + }, + modalView: { + margin: 20, + backgroundColor: 'white', + borderRadius: 20, + padding: 35, + alignItems: 'center', + shadowColor: '#000', + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.25, + shadowRadius: 4, + elevation: 5, + }, + button: { + borderRadius: 20, + padding: 10, + marginVertical: 20, + elevation: 2, + }, + buttonOpen: { + backgroundColor: '#F194FF', + }, + buttonClose: { + backgroundColor: '#2196F3', + }, + textStyle: { + color: 'white', + fontWeight: 'bold', + textAlign: 'center', + }, +}); + +export default ({ + title: "Modal's onShow/onDismiss", + name: 'onShow', + description: + 'onShow and onDismiss (iOS only) callbacks are called when modals is shown/dissmissed', + render: (): React.Node => , +}: RNTesterExampleModuleItem); diff --git a/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js b/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js index 2e2de8635b386b..ffa43987b82c7d 100644 --- a/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js +++ b/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js @@ -112,8 +112,10 @@ class PanResponderExample extends React.Component { styles.circle, // $FlowFixMe[incompatible-type] { - translateX: this.state.left, - translateY: this.state.top, + transform: [ + {translateX: this.state.left}, + {translateY: this.state.top}, + ], backgroundColor: this.state.pressed ? 'blue' : 'green', }, ]} diff --git a/packages/rn-tester/js/examples/SectionList/SectionListExamples.js b/packages/rn-tester/js/examples/SectionList/SectionListExamples.js index 34cd8770e1d54f..f960022a4160bd 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionListExamples.js +++ b/packages/rn-tester/js/examples/SectionList/SectionListExamples.js @@ -226,8 +226,9 @@ export function SectionList_onViewableItemsChanged(props: { viewabilityConfig: ViewabilityConfig, offScreen?: ?boolean, horizontal?: ?boolean, + useScrollRefScroll?: ?boolean, }): React.Node { - const {viewabilityConfig, offScreen, horizontal} = props; + const {viewabilityConfig, offScreen, horizontal, useScrollRefScroll} = props; const [output, setOutput] = React.useState(''); const exampleProps = { onViewableItemsChanged: info => @@ -240,10 +241,19 @@ export function SectionList_onViewableItemsChanged(props: { viewabilityConfig, horizontal, }; + const ref = React.useRef(null); + const onTest = + useScrollRefScroll === true + ? () => { + ref?.current?.getScrollResponder()?.scrollToEnd(); + } + : null; return ( {offScreen === true ? : null} @@ -264,7 +274,7 @@ const SectionListExampleWithForwardedRef = React.forwardRef( {props.testOutput != null ? ( - + {props.testOutput} {props.onTest != null ? ( @@ -327,10 +337,10 @@ const styles = StyleSheet.create({ justifyContent: 'space-between', alignItems: 'center', backgroundColor: '#f2f2f7ff', - padding: 4, height: 40, }, output: { + width: '80%', fontSize: 12, }, separator: { diff --git a/packages/rn-tester/js/examples/Snapshot/SnapshotViewIOS.ios.js b/packages/rn-tester/js/examples/Snapshot/SnapshotViewIOS.ios.js index 3ad7eb33b253af..48f77b2f99dec5 100644 --- a/packages/rn-tester/js/examples/Snapshot/SnapshotViewIOS.ios.js +++ b/packages/rn-tester/js/examples/Snapshot/SnapshotViewIOS.ios.js @@ -22,7 +22,7 @@ import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTyp // Verify that RCTSnapshot is part of the UIManager since it is only loaded // if you have linked against RCTTest like in tests, otherwise we will have // a warning printed out -const RCTSnapshot = UIManager.getViewManagerConfig('RCTSnapshot') +const RCTSnapshot = UIManager.hasViewManagerConfig('RCTSnapshot') ? require('../../../RCTTest/RCTSnapshotNativeComponent') : View; diff --git a/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js b/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js index 794fad91b2d102..d7fda4fc7992fd 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js @@ -23,6 +23,7 @@ const { Switch, Alert, } = require('react-native'); +import type {KeyboardType} from 'react-native/Libraries/Components/TextInput/TextInput'; const TextInputSharedExamples = require('./TextInputSharedExamples.js'); @@ -41,7 +42,10 @@ class WithLabel extends React.Component<$FlowFixMeProps> { } } -class TextInputAccessoryViewExample extends React.Component<{...}, *> { +class TextInputAccessoryViewChangeTextExample extends React.Component< + {...}, + *, +> { constructor(props) { super(props); this.state = {text: 'Placeholder Text'}; @@ -51,6 +55,7 @@ class TextInputAccessoryViewExample extends React.Component<{...}, *> { const inputAccessoryViewID = 'inputAccessoryView1'; return ( + Set InputAccessoryView with ID & reset text: { } } +class TextInputAccessoryViewChangeKeyboardExample extends React.Component< + {...}, + *, +> { + constructor(props) { + super(props); + this.state = {text: '', keyboardType: 'default'}; + } + + _switchKeyboard = () => { + this.setState({ + keyboardType: + this.state.keyboardType === 'default' ? 'number-pad' : 'default', + }); + }; + + render() { + const inputAccessoryViewID = 'inputAccessoryView2'; + return ( + + Set InputAccessoryView with ID & switch keyboard: + this.setState({text})} + value={this.state.text} + keyboardType={this.state.keyboardType} + returnKeyType="done" + /> + + +